NestJSのパイプの作成と利用方法

NestJSでのパイプの作成と利用方法を学びましょう。パイプは、入力データの検証や変換を行うための強力なツールです。

概要

NestJSでは、パイプという機能を利用して、入力データの検証や変換を行うことができます。パイプは主に以下の2つの目的で使用されます。

  1. 変換: 入力データを目的の形式に変換します(例えば、文字列から整数に変換するなど)。
  2. 検証: 入力データを評価し、有効な場合はそのまま渡し、無効な場合は例外をスローします。

パイプは、コントローラのルートハンドラが呼び出される際に適用されます。

デフォルトのパイプ

NestJSは、デフォルトでいくつかのパイプを提供しています。これらのパイプは、@nestjs/commonパッケージからインポートして使用できます。デフォルトで提供されているパイプは以下の6つです。

  1. ValidationPipe: データの検証を行います。
  2. ParseIntPipe: 文字列を整数に変換します。数値に変換できない文字列が渡された場合は例外をスローします。
  3. ParseBoolPipe: 文字列をブール値に変換します。
  4. ParseArrayPipe: 文字列を配列に変換します。
  5. ParseUUIDPipe: 文字列をUUIDに変換します。
  6. DefaultValuePipe: データがnullまたはundefinedの場合にデフォルト値を設定します。

以下に、ParseIntPipeを使用してパラメータを整数に変換する例を示します。

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

@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();
  }
}

上記のコードでは、@Paramデコレータの第二引数にParseIntPipeを指定することで、idパラメータを整数に変換しています。

テスト

# ユーザー一覧の取得
curl http://localhost:3000/users
# ユーザーの追加
curl -X POST -H "Content-Type: application/json" -d '{"name":"Mike"}' http://localhost:3000/users
# ユーザーの更新
curl -X PUT -H "Content-Type: application/json" -d '{"name": "Bob"}' http://localhost:3000/users/1
# ユーザーの削除
curl -X DELETE http://localhost:3000/users/4

カスタムパイプの作成

NestJSでは、独自のパイプを作成することも可能です。これにより、アプリケーション固有のデータ変換や検証を行うことができます。

カスタムパイプを作成するには、まずPipeTransformインターフェースを実装したクラスを作成します。このインターフェースはtransformメソッドを持ち、このメソッドは変換または検証を行う値と、メタデータを引数に取ります。

以下に、カスタムパイプの作成例を示します。

nest g pipe validation

/src/users/validation.pipe.ts

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // ここで値の検証や変換を行う
    return value;
  }
}

上記のコードでは、ValidationPipeという名前のカスタムパイプを作成しています。このパイプは、値とメタデータを引数に取り、値をそのまま返すtransformメソッドを持っています。

まとめ

NestJSのパイプは、入力データの検証や変換を行うための強力なツールです。デフォルトで提供されているパイプを利用することも、独自のパイプを作成することも可能です。これにより、アプリケーションの要件に合わせて、柔軟なデータ処理を実現することができます。