gRPC Interceptors — Complete Guide
In this tutorial, you will learn about grpc interceptors. We cover key concepts, practical examples, and best practices to help you master this topic.
gRPC interceptors are middleware functions that wrap RPC calls. They execute before and after the RPC method, enabling cross-cutting concerns like logging, authentication, metrics collection, tracing, and error handling without modifying service code.
What You'll Learn
- Server-side unary and stream interceptors
- Client-side interceptors
- Interceptor chaining
- Common interceptor use cases
- Implementing interceptors in different languages
Why It Matters
Interceptors keep service logic clean by separating cross-cutting concerns. They enable consistent authentication, monitoring, and error handling across all RPC methods without code duplication.
Real-World Use
Envoy proxy uses gRPC interceptors for traffic management. Jaeger instrumentation uses interceptors for distributed tracing. gRPC ecosystem provides interceptors for logging, auth, and Prometheus metrics.
flowchart TD
Call[RPC Call] --> Interceptor1[Auth Interceptor]
Interceptor1 -->|Pass| Interceptor2[Logging Interceptor]
Interceptor1 -->|Fail| Reject[Reject: Unauthorized]
Interceptor2 --> Interceptor3[Metrics Interceptor]
Interceptor3 --> Service[Service Method]
Service --> Interceptor3
Interceptor3 --> Interceptor2
Interceptor2 --> Response[Response]
Teacher Mindset
Interceptors are the middleware of gRPC. They wrap RPC handlers and can modify the request, response, or context. Use them for infrastructure concerns, not business logic.
Code Examples
// Example 1: Server-side unary interceptor
function authInterceptor(call, callback, next) {
const token = call.metadata.get('authorization')[0];
if (!token) {
return callback(new Error('Unauthorized'));
}
const user = verifyToken(token);
call.user = user;
next(call, callback);
}
server.addService(OrderService, implementation);
server.use(authInterceptor, loggingInterceptor);
// Example 2: Client-side interceptor for logging
function loggingInterceptor(options, nextCall) {
return (call, callback) => {
const start = Date.now();
const newCall = new nextCall(call, callback);
const originalCallback = callback;
newCall.callback = (err, response) => {
const duration = Date.now() - start;
console.log(`${options.method_definition.path} took ${duration}ms`);
originalCallback(err, response);
};
return newCall;
};
}
const client = new OrderService('localhost:50051', grpc.credentials.createInsecure());
client.interceptors = [loggingInterceptor];
// Example 3: Go server interceptor
func loggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
log.Printf("Method: %s", info.FullMethod)
resp, err := handler(ctx, req)
if err != nil {
log.Printf("Error: %v", err)
}
return resp, err
}
server := grpc.NewServer(
grpc.UnaryInterceptor(loggingInterceptor),
grpc.StreamInterceptor(streamLoggingInterceptor),
)
Common Mistakes
- Putting business logic in interceptors instead of service methods
- Not chaining interceptors in the correct order
- Forgetting to handle both success and error paths in stream interceptors
- Creating stateful interceptors that leak data between requests
- Not propagating context values correctly through interceptor chains
Practice
- Implement a logging interceptor that logs method name and duration.
- Add an authentication interceptor that validates JWT tokens.
- Chain the logging and auth interceptors together.
- Create a client-side interceptor for retry logic.
- Challenge: Implement a rate-limiting interceptor using a token bucket algorithm.
FAQ
Mini Project
Add three interceptors to your stock ticker service: auth interceptor that validates an API key from metadata, logging interceptor that logs every RPC call, and metrics interceptor that tracks request counts with Prometheus counter.
What's Next
Next, you will learn about gRPC authentication with SSL/TLS certificates.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro