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 Express4MetricsInterceptor
implements Interceptor<Request, Response>
{
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.