RPC Types in gRPC — Complete Guide
In this tutorial, you will learn about RPC Types in gRPC. We cover key concepts, practical examples, and best practices to help you master this topic.
gRPC supports four RPC types based on streaming patterns. Unary RPC is a single request-response. Server-streaming sends multiple responses. Client-streaming receives multiple requests. Bidirectional streaming handles concurrent streams both ways.
What You'll Learn
- Unary RPC: single request, single response
- Server-streaming: single request, stream of responses
- Client-streaming: stream of requests, single response
- Bidirectional streaming: concurrent streams
- When to choose each RPC type
Why It Matters
Choosing the right RPC type impacts latency, throughput, and client complexity. Server-streaming is ideal for large datasets. Client-streaming suits batch uploads. Bidirectional streaming enables real-time scenarios.
Real-World Use
etcd uses unary for key-value puts, server-streaming for watch notifications, client-streaming for Transaction batches, and bidirectional for lease keep-alives. Google Maps uses server-streaming for route updates.
flowchart LR
subgraph Unary [Unary RPC]
UC[Client] -->|Single Request| US[Server]
US -->|Single Response| UC
end
subgraph ServerStream [Server Streaming]
SSC[Client] -->|Single Request| SSS[Server]
SSS -->|Stream of Responses| SSC
end
subgraph ClientStream [Client Streaming]
CSC[Client] -->|Stream of Requests| CSS[Server]
CSS -->|Single Response| CSC
end
subgraph Bidi [Bidirectional Streaming]
BSC[Client] <-->|Stream both ways| BSS[Server]
end
Teacher Mindset
Start with unary RPC for simple operations. Use server-streaming when the server produces multiple results over time. Use client-streaming when the client sends incremental data. Use bidirectional for real-time interaction.
Code Examples
// Example 1: All four RPC types defined
service ChatService {
// Unary: simple send and receive
rpc SendMessage (Message) returns (MessageAck);
// Server streaming: subscribe to messages
rpc SubscribeMessages (SubscribeRequest) returns (stream Message);
// Client streaming: upload multiple messages
rpc UploadMessages (stream Message) returns (UploadSummary);
// Bidirectional streaming: real-time chat
rpc ChatStream (stream ChatMessage) returns (stream ChatMessage);
}
// Example 2: Client implementation of all types
const client = new ChatService('localhost:50051', grpc.credentials.createInsecure());
// Unary
client.sendMessage({ text: 'Hello' }, (err, ack) => {});
// Server streaming
const sub = client.subscribeMessages({ room: 'general' });
sub.on('data', (msg) => console.log(msg.text));
// Client streaming
const upload = client.uploadMessages((err, summary) => {});
upload.write({ text: 'Batch 1' });
upload.write({ text: 'Batch 2' });
upload.end();
// Bidirectional streaming
const chat = client.chatStream();
chat.on('data', (msg) => console.log('Received:', msg.text));
chat.write({ text: 'Hello', room: 'general' });
// Example 3: Server implementation
const server = new grpc.Server();
server.addService(ChatService, {
sendMessage: (call, callback) => {
callback(null, { id: '1', timestamp: Date.now() });
},
subscribeMessages: (call) => {
const room = call.request.room;
const interval = setInterval(() => {
call.write({ text: 'Live update', room });
}, 1000);
call.on('cancelled', () => clearInterval(interval));
},
uploadMessages: (call, callback) => {
let count = 0;
call.on('data', (msg) => { count++; });
call.on('end', () => callback(null, { count }));
},
chatStream: (call) => {
call.on('data', (msg) => {
call.write({ text: `Echo: ${msg.text}`, room: msg.room });
});
}
});
Common Mistakes
- Using unary RPC for operations that produce incremental results (use server-streaming)
- Forgetting to handle backpressure in streaming RPCs
- Using bidirectional streaming when a unary or server-streaming pattern suffices
- Not implementing proper error handling for stream cancellations
- Ignoring the memory implications of buffering large stream payloads
Practice
- Implement a unary RPC that returns a user profile.
- Implement a server-streaming RPC that returns a stream of product prices.
- Implement a client-streaming RPC that accepts a batch of log entries.
- Implement a bidirectional RPC for a simple echo server.
- Challenge: Benchmark unary vs server-streaming for returning 1000 records.
FAQ
Mini Project
Build a real-time stock ticker service with four RPC types: GetQuote (unary), SubscribeTicker (server-stream), ReportBatch (client-stream), and TraderChat (bidirectional).
What's Next
Next, you will learn about gRPC interceptors for cross-cutting concerns like logging and metrics.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro