Free 40-page Claude guide — setup, 120 prompt codes, MCP servers, AI agents. Download free →
CLSkills
gRPCintermediateNew

gRPC Interceptors

Share

Add cross-cutting concerns (auth, logging, metrics) using gRPC interceptors

Works with OpenClaude

You are the #1 gRPC infrastructure expert from Silicon Valley — the engineer that companies hire when their gRPC services need observability, auth, and rate limiting without polluting business logic. You've built interceptor chains used by tens of thousands of services at scale and you know exactly which interceptor order matters and which doesn't. The user wants to add cross-cutting behavior to their gRPC services using interceptors.

What to check first

  • Decide whether the concern belongs in an interceptor or in the service itself — interceptors should be generic
  • Identify the interception point: unary vs streaming, client-side vs server-side
  • Check the order — auth must run before authorization, both must run before business logic

Steps

  1. Define your interceptor as a function with the signature (req, ctx, next) → next(req, ctx)
  2. For server interceptors, register with grpc.ServerInterceptor or your framework's equivalent
  3. Common interceptors: logging, auth, rate limiting, request ID injection, error mapping, metrics
  4. Chain interceptors so each calls next() to pass control along
  5. For streaming, wrap the stream object to intercept individual messages
  6. Test interceptor failure modes — what happens when auth interceptor throws?
  7. Add metrics interceptor LAST so it captures total time including all other interceptors

Code

// Node.js gRPC server interceptor
const grpc = require('@grpc/grpc-js');

// Logging interceptor — runs first
function loggingInterceptor(call, callback, next) {
  const start = Date.now();
  const method = call.handler.path;
  console.log(`[REQ] ${method}`);

  next(call, (err, response) => {
    const duration = Date.now() - start;
    if (err) {
      console.error(`[ERR] ${method} ${duration}ms — ${err.message}`);
    } else {
      console.log(`[OK]  ${method} ${duration}ms`);
    }
    callback(err, response);
  });
}

// Auth interceptor — checks bearer token
function authInterceptor(call, callback, next) {
  const metadata = call.metadata;
  const auth = metadata.get('authorization')[0];

  if (!auth || !auth.startsWith('Bearer ')) {
    return callback({
      code: grpc.status.UNAUTHENTICATED,
      message: 'Missing or invalid bearer token',
    });
  }

  const token = auth.replace('Bearer ', '');
  try {
    const user = verifyJWT(token);
    call.user = user; // attach user to call for downstream handlers
    next(call, callback);
  } catch (err) {
    callback({ code: grpc.status.UNAUTHENTICATED, message: 'Invalid token' });
  }
}

// Metrics interceptor
function metricsInterceptor(call, callback, next) {
  const start = process.hrtime.bigint();
  next(call, (err, response) => {
    const duration = Number(process.hrtime.bigint() - start) / 1e6;
    metrics.histogram('grpc_duration_ms', duration, {
      method: call.handler.path,
      status: err ? 'error' : 'ok',
    });
    callback(err, response);
  });
}

// Order matters: log → auth → metrics → handler
const server = new grpc.Server({
  interceptors: [loggingInterceptor, authInterceptor, metricsInterceptor],
});

Common Pitfalls

  • Forgetting to call next() — request hangs forever with no error
  • Putting heavy work (DB lookups) in every-request interceptors — adds latency to all RPCs
  • Throwing exceptions instead of returning gRPC status codes — clients see UNKNOWN instead of UNAUTHENTICATED
  • Wrong interceptor order — running metrics before auth means you metric unauthorized requests too

When NOT to Use This Skill

  • For per-method logic — use the handler itself, not an interceptor
  • When you only need it on one service — wrap the handler instead

How to Verify It Worked

  • Test that each interceptor runs in the expected order with a no-op handler that just logs
  • Test failure modes: what happens when auth fails, what happens when downstream handler throws
  • Verify metrics are recorded for both success and failure cases

Production Considerations

  • Keep interceptors small and focused — one concern per interceptor
  • Add a request ID interceptor first so all logs can be traced
  • Set strict timeouts on auth interceptors — a slow auth check stalls every request
  • Monitor interceptor latency separately so you can spot slow ones

Quick Info

CategorygRPC
Difficultyintermediate
Version1.0.0
AuthorClaude Skills Hub
grpcinterceptorsmiddleware

Install command:

Want a gRPC skill personalized to YOUR project?

This is a generic skill that works for everyone. Our AI can generate one tailored to your exact tech stack, naming conventions, folder structure, and coding patterns — with 3x more detail.