How to use NestJS interceptors

Leverage NestJS interceptors to efficiently manage request and response processing.

overview

NestJS provides a powerful feature called interceptors. An interceptor can perform specific logic when a request from a client is passed to the router, or when a response from the router is passed to the client.

Interceptors are mainly used for the following purposes:

  • Bind additional logic before and after method execution
  • transform the result returned from the function
  • convert exceptions thrown from functions
  • Extension of basic functions
  • Overriding functions depending on certain conditions

To create an interceptor, create a class that implements the NestJS NestInterceptor interface and use it where appropriate.

Create an interceptor

New interceptors can be easily created using NestJS’s CLI tools. Let’s run the following command:

nest g itc interceptor/logging

Running this command will create a new interceptor and its test file.

The interceptor we just created hasn’t done anything yet, so we need to add some logic to see it work. This time, I want it to print a string to the console to confirm that the interceptor is working.

/src/users/interceptor/logging/logging.interceptor.ts

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

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before method execution');
    const result = next.handle();
    result.subscribe(() => console.log('After method execution'));
    return result;
  }
}

This interceptor prints messages to the console before and after method execution.

Using interceptors

Just creating an interceptor does nothing yet. In order to use an interceptor you have to configure it in the right place.

This time, let’s configure the interceptor to run when the users path is accessed. It’s easy to set up, use the @UseInterceptors() decorator from the @nestjs/common package in your controller to configure interceptors.

src/users/users.controllers.ts

import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  HttpException,
  HttpStatus,
  Use filters,
  Parse Int Pipe,
  Use Guards,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception/http-exception.filter';
import { AuthGuard } from './guard/auth/auth.guard';

@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  getUsers(): User[] {
    return this.usersService.getUsers();
  }
  @Post()
  addUser(@Body() name: string): void {
    this.usersService.addUser(name);
  }
  @Put(':id')
  putUser(
    @Param('id', ParseIntPipe) id: number,
    @Body('name') name: string,
  ): void {
    this.usersService.putUser(id, name);
  }
  @Delete(':id')
  deleteUser(@Param('id', ParseIntPipe) id: number): void {
    this.usersService.deleteUser(id);
  }
  @Get('throw')
  getException(): string {
    throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
  }
  @Get('custom_throw')
  getCustomException(): string {
    throw new ForbiddenException();
  }
  @Get('guard')
  @UseGuards(AuthGuard)
  getGuard(): string {
    return 'Guard is working';
  }
  @Get('interceptor')
  getInterceptor(): string {
    return 'Interceptor is working';
  }
}

test

curl http://localhost:3000/users/interceptor

summary

NestJS interceptors are powerful tools for efficiently managing request and response processing. It is possible to bind specific logic before and after methods, transform results and exceptions returned by functions, and so on. In addition, various applications are possible depending on the setting method, such as executing an interceptor for all accesses. Take advantage of this feature to manage your application logic more efficiently.