Go - gRPC Streaming & Interceptors

Beginner 10/10 Teacher 10/10 Architect 10/10

gRPC Streaming & Interceptors

gRPC supports unary, server-streaming, client-streaming, and bidirectional RPCs. Interceptors add middleware-like functionality.

Try it: Define a server-streaming RPC in your .proto and implement it in Go.

Server streaming (concept)

// .proto
// rpc ListItems(Request) returns (stream Item) {}
// Go server
// func (s *svc) ListItems(req *pb.Request, stream pb.Service_ListItemsServer) error {
//   for _, it := range items { if err := stream.Send(it); err != nil { return err } }
//   return nil
// }

Unary interceptors

func loggingInterceptor(
  ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler,
) (any, error) {
  start := time.Now()
  resp, err := handler(ctx, req)
  log.Printf("method=%s dur=%s err=%v", info.FullMethod, time.Since(start), err)
  return resp, err
}

// server := grpc.NewServer(grpc.UnaryInterceptor(loggingInterceptor))

Common errors

  • Blocking streams without deadlines/cancellation.
  • Not handling backpressure—send loops should respect context.

Practice

  • Add a client-side interceptor to inject a request ID into metadata.

Quick quiz

  1. Where do interceptors run in the call lifecycle?
Show answer Around the handler—before and after invoking it, similar to middleware.