Class BowireGraphQLProtocol
- Namespace
- Kuestenlogik.Bowire.Protocol.GraphQL
- Assembly
- Kuestenlogik.Bowire.Protocol.GraphQL.dll
Bowire protocol plugin for GraphQL. Discovers a remote schema via introspection (Kuestenlogik.Bowire.Protocol.GraphQL.GraphQLIntrospectionQuery), surfaces the query / mutation / subscription root operations as services, and invokes them by building a parameterised operation string with Kuestenlogik.Bowire.Protocol.GraphQL.GraphQLQueryBuilder.
public sealed class BowireGraphQLProtocol : IBowireProtocol, IBowireProxySupport, IDisposable
- Inheritance
-
BowireGraphQLProtocol
- Implements
- Inherited Members
Constructors
BowireGraphQLProtocol()
public BowireGraphQLProtocol()
Fields
BatchMetadataKey
Optional metadata key. Set to on to send several documents in
one request as a JSON array, the way a batching server expects
(#713).
public const string BatchMetadataKey = "X-Bowire-GraphQL-Batch"
Field Value
Remarks
InvokeAsync(string, string, string, List<string>, bool, Dictionary<string, string>?, CancellationToken) has always taken a list of messages, and this plugin has always read only the first. Every further one was dropped without a word. Batching is what makes that plural mean something.
Opt-in, because a server that does not batch answers an array with a parse error, and the caller would have no idea why a request that works one at a time fails together.
Not combined with GET (an array has no sensible URL form) or with APQ (a batch would need a hash per entry and a retry per miss — buildable, but nobody has asked, and guessing at the shape would pin a convention servers do not agree on).
HttpMethodMetadataKey
Optional metadata key. Set to get to send queries over
GET instead of POST (#713).
public const string HttpMethodMetadataKey = "X-Bowire-GraphQL-Http-Method"
Field Value
Remarks
Bowire has always posted. That works against nearly every server and is the right default, but it leaves two cases unreachable: a CDN or cache in front of the API, which can only cache a GET, and a server configured to accept queries over GET alone.
Opt-in rather than automatic, because the choice has consequences a caller should make deliberately: a GET puts the whole document in the URL, where proxies and access logs keep it, and long documents meet a URL length limit nobody controls.
MultiplexMetadataKey
Optional metadata key. Set to on to share one
graphql-transport-ws socket across subscriptions to the same
endpoint (#713).
public const string MultiplexMetadataKey = "X-Bowire-GraphQL-Multiplex"
Field Value
Remarks
The protocol was built for this: every message carries an operation id so one connection can serve many. Without it each subscription opens its own socket, which is correct but wasteful against a server with a connection limit or an expensive auth handshake.
Opt-in, and deliberately so rather than for symmetry with the other flags. A shared socket means one failure reaches several callers, and the one-socket-per-subscription path has years of use behind it while this has none. The flag is how this earns the mileage to become the default.
PersistedQueryMetadataKey
Optional metadata key. Set to on to use Automatic Persisted
Queries: send a SHA-256 of the document and let the server run it
from its own store (#713).
public const string PersistedQueryMetadataKey = "X-Bowire-GraphQL-Persisted-Query"
Field Value
Remarks
The saving is the whole document on every request after the first. Behind a per-request body limit, or on a link where the document is the expensive part, that is the difference between workable and not.
Opt-in because it costs an extra round trip the first time a server sees a document, and a caller that sends one query once pays that cost for nothing.
SubscriptionTransportMetadataKey
Optional metadata key. Set to ws to force the
graphql-transport-ws transport, or sse to force graphql-sse.
When unset, the plugin tries WebSocket first (if the WebSocket plugin
is loaded) and falls back to SSE.
public const string SubscriptionTransportMetadataKey = "X-Bowire-GraphQL-Subscription-Transport"
Field Value
Properties
Description
One-line description shown next to the plugin's display name
in Settings → Plugins. Optional; defaults to empty so
the row falls back to "DisplayName + version" without the
description line. Keep it short (≤ 100 characters) — the row
truncates anything wider than the manage panel.
public string Description { get; }
Property Value
DescriptionKey
#691 — optional catalogue key for Description. When the workbench's active locale has an entry for it, that entry is shown; otherwise Description is, exactly as before. Third-party plugins leave it empty and keep today's behaviour.
public string DescriptionKey { get; }
Property Value
IconSvg
SVG icon for the protocol tab.
public string IconSvg { get; }
Property Value
Id
Short identifier (e.g., "grpc", "signalr").
public string Id { get; }
Property Value
Name
Protocol name shown in UI tabs.
public string Name { get; }
Property Value
ProxySupport
How far this plugin's connections follow the proxy.
public BowireProxySupport ProxySupport { get; }
Property Value
Methods
DiscoverAsync(string, bool, CancellationToken)
Discover available services and methods.
public Task<List<BowireServiceInfo>> DiscoverAsync(string serverUrl, bool showInternalServices, CancellationToken ct = default)
Parameters
serverUrlstringshowInternalServicesboolctCancellationToken
Returns
Dispose()
Dispose the lazily-built HttpClient. Same lifecycle contract as the REST plugin — the registry that owns the plugin instance disposes it at host shutdown.
public void Dispose()
Initialize(IServiceProvider?)
Called after registration to inject the app's service provider (embedded mode).
public void Initialize(IServiceProvider? serviceProvider)
Parameters
serviceProviderIServiceProvider
InvokeAsync(string, string, string, List<string>, bool, Dictionary<string, string>?, CancellationToken)
Invoke a unary or client-streaming call.
public Task<InvokeResult> InvokeAsync(string serverUrl, string service, string method, List<string> jsonMessages, bool showInternalServices, Dictionary<string, string>? metadata = null, CancellationToken ct = default)
Parameters
serverUrlstringservicestringmethodstringjsonMessagesList<string>showInternalServicesboolmetadataDictionary<string, string>ctCancellationToken
Returns
InvokeStreamAsync(string, string, string, List<string>, bool, Dictionary<string, string>?, CancellationToken)
Invoke a server-streaming or duplex call.
public IAsyncEnumerable<string> InvokeStreamAsync(string serverUrl, string service, string method, List<string> jsonMessages, bool showInternalServices, Dictionary<string, string>? metadata = null, CancellationToken ct = default)
Parameters
serverUrlstringservicestringmethodstringjsonMessagesList<string>showInternalServicesboolmetadataDictionary<string, string>ctCancellationToken
Returns
OpenChannelAsync(string, string, string, bool, Dictionary<string, string>?, CancellationToken)
Open an interactive channel (for duplex/client-streaming).
public Task<IBowireChannel?> OpenChannelAsync(string serverUrl, string service, string method, bool showInternalServices, Dictionary<string, string>? metadata = null, CancellationToken ct = default)
Parameters
serverUrlstringservicestringmethodstringshowInternalServicesboolmetadataDictionary<string, string>ctCancellationToken