Class BowireGrpcProtocol
- Namespace
- Kuestenlogik.Bowire.Protocol.Grpc
- Assembly
- Kuestenlogik.Bowire.Protocol.Grpc.dll
gRPC protocol plugin for Bowire. Discovers services via gRPC Server Reflection and invokes methods using dynamic protobuf marshalling.
Implements IBowireProtocolServices so that
builder.Services.AddBowire() automatically registers
AddGrpcReflection() and app.MapBowire() maps
MapGrpcReflectionService() — no manual setup required.
public sealed class BowireGrpcProtocol : IBowireProtocol, IBowireProxySupport, IBowireProtocolServices, IBowireStreamingWithWireBytes
- Inheritance
-
BowireGrpcProtocol
- Implements
- Inherited Members
Constructors
BowireGrpcProtocol()
public BowireGrpcProtocol()
Fields
TransportMetadataKey
Metadata key callers use to opt into gRPC-Web transport for a single
call. Value is "web" (case-insensitive) for gRPC-Web, anything else
(or absence) for the default native HTTP/2 gRPC. Symmetric to the
grpcweb@ URL hint, which Bowire's discovery + invoke endpoints
translate into this header before dispatching to the plugin.
Spelled X-Bowire-Grpc-Transport so it travels safely through
every HTTP intermediary as a regular request header — gRPC strips
HTTP/2 pseudo-headers, but custom x--prefixed entries pass
through both native gRPC trailers and gRPC-Web's HTTP framing.
public const string TransportMetadataKey = "X-Bowire-Grpc-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
ProxyNote
One sentence on what goes direct and why, for Partial and None.
public string? ProxyNote { get; }
Property Value
ProxyNoteKey
The catalogue key for ProxyNote (#691): the workbench shows the translation and falls back to the English note.
public string? ProxyNoteKey { get; }
Property Value
ProxySupport
How far this plugin's connections follow the proxy.
public BowireProxySupport ProxySupport { get; }
Property Value
Methods
ConfigureServices(IServiceCollection)
Registers gRPC Reflection services so Bowire can discover gRPC services
automatically. Called by builder.Services.AddBowire().
Idempotent — safe to call even if the host already called AddGrpcReflection().
public void ConfigureServices(IServiceCollection services)
Parameters
servicesIServiceCollection
DiscoverAsync(string, bool, IReadOnlyDictionary<string, string>?, CancellationToken)
Same, with the per-call metadata InvokeAsync(string, string, string, List<string>, bool, Dictionary<string, string>?, CancellationToken) already receives.
public Task<List<BowireServiceInfo>> DiscoverAsync(string serverUrl, bool showInternalServices, IReadOnlyDictionary<string, string>? metadata, CancellationToken ct = default)
Parameters
serverUrlstringshowInternalServicesboolmetadataIReadOnlyDictionary<string, string>ctCancellationToken
Returns
Remarks
Discovery was the one operation with no way to carry configuration, and it is the operation that decides whether anything else can run at all. A gRPC server with reflection switched off could be invoked once a descriptor set was supplied, but could not be enumerated — so a scan could not find the methods it was meant to test, and mTLS-protected servers could not be reflected against at all.
A default implementation that drops the metadata, so a plugin with no
per-environment configuration to honour stays exactly as it is. Only a
plugin that already reads a marker out of metadata elsewhere has
any reason to override it.
DiscoverAsync(string, bool, CancellationToken)
Discover available services and methods.
public Task<List<BowireServiceInfo>> DiscoverAsync(string serverUrl, bool showInternalServices, CancellationToken ct)
Parameters
serverUrlstringshowInternalServicesboolctCancellationToken
Returns
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, CancellationToken ct)
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, CancellationToken ct)
Parameters
serverUrlstringservicestringmethodstringjsonMessagesList<string>showInternalServicesboolmetadataDictionary<string, string>ctCancellationToken
Returns
InvokeStreamWithFramesAsync(string, string, string, List<string>, bool, Dictionary<string, string>?, CancellationToken)
Binary-aware server-streaming invocation. Yields each frame's wire bytes alongside its JSON rendering so the Bowire recorder can persist the binary payload per frame — Phase-2d gRPC-streaming mock replay needs the original bytes to re-emit without runtime JSON→protobuf re-encoding.
public IAsyncEnumerable<StreamFrame> InvokeStreamWithFramesAsync(string serverUrl, string service, string method, List<string> jsonMessages, bool showInternalServices, Dictionary<string, string>? metadata, CancellationToken ct)
Parameters
serverUrlstringservicestringmethodstringjsonMessagesList<string>showInternalServicesboolmetadataDictionary<string, string>ctCancellationToken
Returns
MapDiscoveryEndpoints(IEndpointRouteBuilder)
Maps the gRPC Reflection endpoint so clients (including Bowire's own
discovery) can query the server's service descriptors at runtime.
Called by app.MapBowire().
public void MapDiscoveryEndpoints(IEndpointRouteBuilder endpoints)
Parameters
endpointsIEndpointRouteBuilder
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, CancellationToken ct)
Parameters
serverUrlstringservicestringmethodstringshowInternalServicesboolmetadataDictionary<string, string>ctCancellationToken