Skip to main content

grpc

gRPC transport for Webda — exposes registered operations as gRPC services over HTTP/2, with auto-generated .proto files 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 .proto file that stays in sync with your operation registry automatically on every webdac build.

Install​

pnpm add @webda/grpc

Configuration​

{
"services": {
"grpc": {
"type": "GrpcService",
"protoFile": ".webda/app.proto",
"packageName": "webda"
}
}
}
ParameterTypeDefaultRequiredDescription
protoFilestring".webda/app.proto"NoPath where the generated .proto file is written and loaded from
packageNamestring"webda"NoProtobuf package name used in the generated .proto
maxQueuedMessagesnumber1000NoMost unconsumed messages a client or bidirectional call may queue; above it the call fails with RESOURCE_EXHAUSTED
maxQueuedBytesnumber16777216NoMost 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/graphql for the GraphQL transport; @webda/core for the OperationsTransport base class and operation registration.

Classes​

Interfaces​

Variables​

Functions​