NestJSのインターセプターの使用方法

NestJSのインターセプターを活用して、リクエストとレスポンスの処理を効率的に管理しましょう。

概要

NestJSでは、インターセプターという強力な機能を提供しています。インターセプターは、クライアントからのリクエストがルーターに渡されるとき、またはルーターからのレスポンスがクライアントに渡されるときに、特定のロジックを実行することができます。

インターセプターは主に以下のような目的で使用されます:

  • メソッド実行の前後に追加のロジックをバインドする
  • 関数から返された結果を変換する
  • 関数からスローされた例外を変換する
  • 基本的な機能の拡張
  • 特定の条件に応じて関数のオーバーライド

インターセプターを作成するには、NestJSのNestInterceptorインターフェースを実装したクラスを作成し、それを適切な場所で使用します。

インターセプターの作成

NestJSのCLIツールを使用して、新しいインターセプターを簡単に作成することができます。以下のコマンドを実行してみましょう:

nest g itc interceptor/logging

このコマンドを実行すると、新しいインターセプターとそのテストファイルが作成されます。

作成されたインターセプターは、まだ何も処理を設定していないため、動作を確認するためには何らかのロジックを追加する必要があります。今回は、インターセプターが動作することを確認するために、コンソールに文字列を出力するようにします。

/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;
  }
}

このインターセプターは、メソッドの実行前後にコンソールにメッセージを出力します。

インターセプターの使用

インターセプターを作成しただけではまだ何も起こりません。インターセプターを使用するためには、それを適切な場所で設定する必要があります。

今回は、usersパスにアクセスされた場合にインターセプターを実行するように設定してみましょう。設定は簡単で、コントローラーで@nestjs/commonパッケージの@UseInterceptors()デコレータを使用してインターセプターを設定します。

src/users/users.controllers.ts

import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  HttpException,
  HttpStatus,
  UseFilters,
  ParseIntPipe,
  UseGuards,
} 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';
  }
}

テスト

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

まとめ

NestJSのインターセプターは、リクエストとレスポンスの処理を効率的に管理するための強力なツールです。特定のロジックをメソッドの前後にバインドしたり、関数から返された結果や例外を変換したりすることが可能です。また、全てのアクセスに対してインターセプターを実行するなど、設定方法によってはさまざまな応用が可能です。この機能を活用して、アプリケーションのロジックをより効率的に管理しましょう。