Skip to main content

Interceptor

Interceptors run around your route handler—before it executes and after it completes. They can inspect the request/response, short-circuit the flow, and even transform the handler result.

Interceptors must implement the Interceptor<TRequest, TResponse> interface:

interface Interceptor<TRequest = any, TResponse = any> {
intercept(
request: TRequest,
response: TResponse,
next: () => Promise<InterceptorTransformObject>,
): Promise<void>;
}

interface InterceptorTransformObject {
push: (transform: (value: unknown) => unknown) => void;
}

intercept​

  • Before the handler: do any pre-work (metrics, logging, auth checks, etc.).
  • Call await next() to hand control to the next interceptor or the controller handler.
  • After the handler: continue work (timers, audit logs, publish events, etc.).
  • To modify the handler return value, use the returned InterceptorTransformObject and call transform.push(fn); your fn receives the handler result and should return the transformed value.

Adapter-specific examples​

Each adapter exposes its own native request/response types. Below is a simple “metrics” interceptor that increments a counter for the request path, running both before and after the handler.

const METRICS: Record<string, number> = {};

function registerMetrics(path: string): void {
METRICS[path] = (METRICS[path] ?? 0) + 1;
}

export class ExpressMetricsInterceptor implements ExpressInterceptor {
public async intercept(
request: Request,
_response: Response,
next: () => Promise<unknown>,
): Promise<void> {
const path: string = request.path;

// before handler
registerMetrics(path);

await next();

// after handler
registerMetrics(path);
}
}

Transforming the handler result​

Interceptors can transform the value returned by your controller method. After await next(), use the returned transform object:

transform.push((value) => ({ ...value, intercepted: true }));

Under the hood, the adapter chains all registered transforms and applies them to the handler result before sending the response.

Attaching interceptors​

Use the UseInterceptor decorator at the controller level (applies to all routes) or at the method level (applies to a single route).

Global interceptors can be registered using the InversifyHttpAdapter.