NestJSのカスタムデコレータの作成と利用

NestJSでのカスタムデコレータの作成と利用方法を学びましょう。

概要

NestJSでは、カスタムデコレータを利用して、特定のデータを抽出したり、クラスやメソッドに特定のメタデータを追加したりすることができます。カスタムデコレータは、リクエストオブジェクトから特定のデータを取得するときや、依存関係の注入といった処理を簡素化したい場合に非常に有用です。

カスタムデコレータを作成する方法

カスタムデコレータを作成するには、まずcreateParamDecorator関数を使用して新しいデコレータを作成します。以下に、認証されたユーザーの情報をリクエストから取得するためのカスタムデコレータを作成する例を示します。

便利なCLIがあるので、それを使って作成します。

nest g d users/decorator/user

/src/users/decorators/user/user.decorator.ts

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.body.user;
  },
);

上記のコードでは、Userという名前のカスタムデコレータを作成しています。このデコレータは、実行コンテキストからHTTPリクエストオブジェクトを取得し、そのユーザー情報を返します。

カスタムデコレータを利用する方法

作成したカスタムデコレータを利用するには、そのデコレータをメソッドのパラメータに適用します。以下に、作成したカスタムデコレータを利用する例を示します。

/src/users/users.controller.ts

import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  HttpException,
  HttpStatus,
  UseFilters,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception/http-exception.filter';
import { User } from './decorator/user/user.decorator';

@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') id: number, @Body('name') name: string): void {
    this.usersService.putUser(id, name);
  }

  @Delete(':id')
  deleteUser(@Param('id') 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();
  }
  @Post('custom_decorator')
  getCustomDecorator(@User() user: User) {
    return user;
  }
}

上記のコードでは、ProfileControllergetProfileメソッドで@User()デコレータを使用しています。これにより、リクエストからユーザー情報が自動的に抽出され、getProfileメソッドのuserパラメータに注入されます。

テスト

curl -X POST http://localhost:3000/users/custom_decorator -H 'Content-Type: application/json' -d '{"user": {"name": "test"}}'

まとめ

NestJSでは、カスタムデコレータを利用して、リクエストオブジェクトから特定のデータを抽出したり、クラスやメソッドに特定のメタデータを追加したりすることができます。これにより、より柔軟なコーディングと処理の簡素化が可能になります。