gRPC Microservices
gRPC Microservices
gRPC is a high-performance, open-source RPC framework developed by Google. It uses Protocol Buffers (protobuf) as its interface definition language and wire format, giving you strongly-typed service contracts, efficient binary serialisation, and native support for bidirectional streaming — all critical for production microservice communication.
Why gRPC instead of REST?
- Strongly-typed contracts — the
.protofile is the single source of truth; both client and server are generated from it, eliminating drift. - Binary serialisation — protobuf is 3–10× more compact and faster to parse than JSON.
- Streaming support — server-side, client-side, and bidirectional streams are first-class citizens.
- Code generation — TypeScript types are generated automatically, preventing entire classes of runtime errors.
Defining a protobuf service
Everything starts with a .proto file. It declares your messages (data shapes) and the service (the RPC methods). Place it in a shared proto/ directory at the repository root so both the server and client can reference the same file:
Setting up the gRPC transporter in NestJS
Install the required packages, then configure main.ts to start a microservice with the gRPC transporter:
Implementing gRPC handlers with @GrpcMethod
Use the @GrpcMethod() decorator to map a controller method to an RPC definition. The method name must match the RPC name in the .proto (or be supplied as the second argument):
Unary vs streaming calls
- Unary — one request, one response (standard HTTP-like). Handled by a plain method returning a value or Promise.
- Server-streaming — one request, a stream of responses. Return an
Observablefrom the handler; NestJS will emit each value as a separate protobuf message. - Client-streaming / Bidirectional — accept an
Observableas the first argument. Advanced patterns for real-time scenarios.
Observable from a @GrpcMethod handler automatically converts it to a gRPC server stream, keeping your code clean and testable.
Calling a gRPC service from a NestJS client
Inject the gRPC client via @Inject() after registering it as a ClientsModule provider. The client proxy gives you a typed stub matching the .proto interface:
ts-proto or protoc with the TypeScript plugin to generate accurate types and keep them in sync whenever the proto changes.
Summary
gRPC microservices in NestJS follow a clear pattern: define the contract in a .proto file, configure the Transport.GRPC transporter in main.ts, and annotate handlers with @GrpcMethod(). Unary calls return plain values or Promises; server-streaming calls return RxJS Observables. Clients register a ClientsModule provider and call the remote service with full type safety. The protobuf contract ensures both sides speak the same language — even across different programming languages.