grpc
gRPC transport for Webda — exposes registered operations as gRPC services over HTTP/2, with auto-generated
.protofiles from the operation registry.
When to use it
- You want to expose Webda operations to gRPC clients (mobile apps, microservices, inter-service calls) alongside the existing REST API.
- You are running the multi-protocol dev server (
webda debug) and need gRPC on the same TLS port as REST and GraphQL. - You need a generated
.protofile that stays in sync with your operation registry automatically on everywebdac build.
Install
pnpm add @webda/grpc
Configuration
{
"services": {
"grpc": {
"type": "GrpcService",
"protoFile": ".webda/app.proto",
"packageName": "webda"
}
}
}
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
protoFile | string | ".webda/app.proto" | No | Path where the generated .proto file is written and loaded from |
packageName | string | "webda" | No | Protobuf package name used in the generated .proto |
maxQueuedMessages | number | 1000 | No | Most unconsumed messages a client or bidirectional call may queue; above it the call fails with RESOURCE_EXHAUSTED |
maxQueuedBytes | number | 16777216 | No | Most bytes of unconsumed messages a client or bidirectional call may queue; above it the call fails with RESOURCE_EXHAUSTED |
Usage
// 1. Annotate operations in your model/service:
import { Operation } from "@webda/core";
export class PostService extends Service {
@Operation({ input: "CreatePostInput", output: "Post" })
async createPost(ctx: OperationContext<CreatePostInput>): Promise<Post> {
const body = await ctx.getInput();
return new Post(body).save();
}
}
// 2. Build to generate the .proto file:
// webdac build
// → writes .webda/app.proto
// 3. Start the server (gRPC is multiplexed on the same port as REST):
// webda serve
// → gRPC requests with content-type: application/grpc are routed to GrpcService
// 4. Call from a gRPC client (example using grpcurl):
// grpcurl -plaintext -d '{"title":"Hello"}' localhost:18080 webda.PostService/CreatePost
Streaming
All four modes (unary, server, client and bidirectional streams) are live: messages are sent as the generator yields,
and input messages reach the operation as they are received. Request metadata is readable through
useContext().getHttpContext(). See Operations for the
signatures, and for the same async *connect(frames) served as a WebSocket by the REST transport.
Messages are the JSON-equivalent objects of the operation: a chunk that is not an object is sent as { value } and
__-prefixed keys never leave the server. A compressed message ends the call with UNIMPLEMENTED, a message over
4 MiB (GRPC_MAX_MESSAGE_SIZE) with RESOURCE_EXHAUSTED, and one that cannot be decoded with INVALID_ARGUMENT. When
the client cancels, the generator's return() is called so its finally runs; an operation that throws
OperationCancelledError while the client is still connected ends with CANCELLED.
Reference
- API reference: see the auto-generated typedoc at
docs/pages/Modules/grpc/. - Source:
packages/grpc - Related:
@webda/graphqlfor the GraphQL transport;@webda/corefor theOperationsTransportbase class and operation registration.