Menu
CoddyTech

Interceptors

Part of the TypeScript and NestJS section of Coddy's Node.js journey. Lesson 16 of 17.

You want every answer to say how long it took, without touching each handler. An interceptor wraps the handler: code before next.handle() runs before it, and code on what next.handle() returns runs after it.

intercept(context: ExecutionContext, next: CallHandler) {
    console.log('before');
    return next.handle().pipe(
        tap(() => console.log('after')),
    );
}

next.handle() gives the handler's result as an RxJS observable, a value that arrives later. pipe(tap(...)) runs a function when it arrives, before Nest sends it. Return the piped observable: Nest sends what it carries. context.switchToHttp().getResponse() gives res, whose setHeader adds a header.

app.useGlobalInterceptors(...) applies an interceptor to every route; @UseInterceptors(...) to one controller.

challenge icon

Challenge

Easy
  • Finish ResponseTimeInterceptor: every answer carries X-Response-Time, the milliseconds the handler took, like 3ms.
  • Register it for the whole app.
  • Send GET /tasks and GET /stats and open the Headers tab, then send POST /tasks without a key.

Try it yourself

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, tap } from 'rxjs';

@Injectable()
export class ResponseTimeInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
        // Note the time, let the handler run, then set X-Response-Time.
        return next.handle();
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in TypeScript and NestJS