Under The Hood
backend nestjs NestJS 10+

Interceptors: CallHandler, next.handle(), and RxJS Response Pipelines

Last updated
Prerequisites:
NestJS ExecutionContext
RxJS Observables and Operators (`map`, `tap`, `catchError`)
  • nestjs
  • interceptors
  • rxjs
  • callHandler
  • aop
  • response-mapping

Read at your depth

The practical view

Interceptors implement the `NestInterceptor` interface with `intercept(context, next: CallHandler): Observable<any>`. They use Aspect-Oriented Programming (AOP) to bind extra logic before and after method execution. By calling `next.handle()`, you invoke the route handler and receive an RxJS `Observable` of the response, which you can transform using operators like `map()` (wrap response in `{ data: ... }`), `tap()` (log execution time), or `timeout()`.

The same idea in other frameworks

nestjs equivalent
`return next.handle().pipe(map(data => ({ data })))`.

Legacy vs modern

Manual Controller Response Wrapping vs Global Transform Interceptor

Manually wrapping responses in `{ data: ... }` pollutes controller logic; an Interceptor normalizes all API responses cleanly.

before → after
Manual Controller Envelope Wrapping
return { data: users, timestamp: Date.now() }; // ❌ Duplicated across every controller
RxJS Transform Interceptor
return next.handle().pipe(map(data => ({ data, timestamp: new Date().toISOString() }))); // ✅ NEW

Interview gotchas

Context

Interviewers test your knowledge of interceptor pipeline propagation.

The mechanical answer

If you do not call `next.handle()`, the **route handler method will never be executed**. You can use this behavior deliberately to short-circuit requests (e.g. returning cached responses directly from memory via `of(cachedData)` without hitting the controller or database).

Trap

Returning a plain value without calling `next.handle()` or returning an `Observable` will hang the HTTP connection.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.