The gRPC service applications use to register Connect/gRPC services.
The default basePath is the root (DEFAULT_BASE_PATH): a gRPC-family
client derives its path from the method name alone and has no prefix option,
so a prefixed default serves every procedure at an address no such client
asks for. At the root, claims() reports only registered procedure paths, so
the kernel consults this service before route matching without shadowing
ordinary routes. Connect and gRPC-Web are then served at their natural
addresses; native application/grpc is refused with a Trailers-Only
UNIMPLEMENTED. Pass basePath: '/grpc' to restore the pre-M70i prefix.
available: boolean
Whether gRPC dispatch is available. Always true since the kernel now
resolves IGrpcService from the service registry and dispatches after
the middleware pipeline (M70a). The previous adapter-based seam is retired.
serviceCount: number
Number of application services registered. Read by the health indicator.
addService<TDef extends GrpcServiceDefinition>(definition: TDef,implementation?: unknown): void
Registers a gRPC service definition with an optional implementation.
Whether this service claims the request's path — that is, whether the path
lies inside the configured basePath.
The kernel calls this before GrpcService.handleRequest, which
answers 404 for a claimed path with no matching procedure and therefore
cannot itself be used to tell "not mine" from "mine, but unknown". Without
this guard every unmatched route in the application would be answered by
gRPC's plain-text 404 instead of the kernel's JSON one.
A root basePath is the exception, and it is load-bearing: ''
contains every path, so a prefix test would claim the entire application.
The kernel consults claims before route matching, so that would 404 every
ordinary route. At the root this therefore claims only paths it can
actually serve, mirroring the asymmetry dispatchRequest already
documents — "not a known procedure" and "an ordinary application route"
are indistinguishable there, so both fall through.
Inside a non-root base path the prefix IS the claim, so an unknown
procedure under /grpc answers gRPC's 404 rather than falling through to
the application — the M49 behaviour.
close(): void
Releases the built router and its handlers. Afterwards the plugin's own
procedures answer 503 instead of rebuilding a router for an application
that is shutting down, while every other path falls through untouched.
createFetchHandler(): RpcFetchHandler
The handler that used to be installed into IHttpAdapter.setRpcHandler.
Returns null for any request outside basePath.
handleRequest(request: Request): Promise<Response>
Handles an RPC request directly.
Returns a 404 response when the request does not match any registered
service path. Callers routing traffic should consult
GrpcService.claims first.
Refuses a native application/grpc request from its HEADERS alone.
The refusal itself is M70i's and unchanged: the fetch Response cannot
carry the HTTP/2 trailers the native wire format signals completion with,
so a Trailers-Only UNIMPLEMENTED is the protocol's own way to say so.
What changed is WHEN it is reachable.
The kernel used to buffer the request body before dispatching, and a
client-streaming or bidirectional call holds its request stream OPEN — so
that read never resolved and the caller got no frames at all instead of
the refusal (V5-5). grpcurl opens a bidirectional reflection stream
first, which is why it hung on every request while a unary probe with the
stream closed received the refusal correctly.
Deciding this from headers costs nothing: the content type is all the
answer depends on, and the path check is the same claims already made.