How to Build a gRPC Service
Define a gRPC service in Protocol Buffers, generate server and client code, implement unary and server-streaming methods, and call the service with deadlines and interceptors.
What and why
gRPC is a high-performance RPC framework using Protocol Buffers for a compact binary contract and HTTP/2 for multiplexed, streaming transport. It suits internal service-to-service communication where low latency and strong typing matter more than browser friendliness.
Prerequisites
- Go or Node.js installed.
protocorbuffor code generation.- Basic understanding of RPC.
Steps
1. Define the service in protobuf
syntax = "proto3";
package orders.v1;
service OrderService {
rpc GetOrder(GetOrderRequest) returns (Order);
rpc WatchOrders(WatchRequest) returns (stream Order);
}
message GetOrderRequest { string id = 1; }
message WatchRequest { string customer_id = 1; }
message Order { string id = 1; string status = 2; }
2. Generate code
With buf:
buf generate
Or protoc directly to generate stubs for your language. This produces typed server interfaces and client stubs.
3. Implement the server
Go example for the unary method:
func (s *server) GetOrder(ctx context.Context, req *pb.GetOrderRequest) (*pb.Order, error) {
o, err := s.store.Find(req.Id)
if err != nil {
return nil, status.Error(codes.NotFound, "order not found")
}
return &pb.Order{Id: o.ID, Status: o.Status}, nil
}
4. Add a streaming method
Server streaming sends many messages on one call:
func (s *server) WatchOrders(req *pb.WatchRequest, stream pb.OrderService_WatchOrdersServer) error {
for o := range s.updates(req.CustomerId) {
if err := stream.Send(o); err != nil { return err }
}
return nil
}
5. Call from a client
conn, _ := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
client := pb.NewOrderServiceClient(conn)
order, _ := client.GetOrder(ctx, &pb.GetOrderRequest{Id: "42"})
6. Add interceptors and deadlines
Use interceptors for cross-cutting concerns (auth, logging, metrics) and always set a deadline on client calls with context.WithTimeout so slow servers cannot hang callers.
Verification
- Code generation produces server and client stubs.
- A unary call returns the expected message.
- A streaming call delivers multiple messages.
- A call past its deadline returns
DeadlineExceeded.
Next Steps
Secure the channel with TLS or mTLS, add a gRPC health check service, expose a gRPC-Web or REST gateway for browser clients, and load-test with proper connection reuse since gRPC multiplexes over a single connection.
Prerequisites
- Go or Node.js installed
- protoc or buf installed
- Basic understanding of RPC
Steps
- 1Define the service in protobuf
- 2Generate code
- 3Implement the server
- 4Add a streaming method
- 5Call from a client
- 6Add interceptors and deadlines