前回
パイプ
パイプは、@Injectable()
デコレータがつけられたクラスで、PipeTransform
インターフェースを実装します。
パイプは、2通りの使用例があります。
- transformation
- 入力データを目的の形式に変換します。文字列から整数へなど
- validation
- 入力データを評価し、有効な場合はそのまま渡しますが、有効でない場合は、例外をスローします。
いずれの場合も、パイプはコントローラのルートハンドラによって処理される引数に対して動作します。
Nestは、メソッドが呼び出される直前にパイプを挿入し、パイプはメソッド宛の引数を受け取り、それらを操作します。
この操作の時点でtransformationまたはvalidationが実施され、その後処理済みの引数を利用して、ルートハンドラが呼び出されます。
Nestには、組み込みパイプと、カスタムパイプがあります。
組み込みパイプ
Nestには、以下の組み込みパイプがあります。
- ValidationPipe
- ParseIntPipe
- ParseFloatPipe
- ParseBoolPipe
- ParseArrayPipe
- ParseUUIDPipe
- ParseEnumPipe
- DefaultValuePipe
- ParseFilePipe
パイプをバインドする
パイプをコントローラにバインドしてみましょう。
src/cats/cats.controller.ts
import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get(':id') findOne(@Param('id', ParseIntPipe) id: number) { return id; } }
@Param
に、ParseIntPipe
をバインドしました。
postman
で、GET localhost:3000/cats/12345
を呼び出すと、以下のように返却されます。
12345
一方で、GET localhost:3000/cats/abcde
を呼び出すと、以下のように返却されます。
{ "statusCode": 400, "message": "Validation failed (numeric string is expected)", "error": "Bad Request" }
カスタムパイプ
独自のカスタムパイプを作成してみましょう。
$ nest g pipe pipe/validation
以下のファイルが作成されました。
src/pipe/validation/validation.pipe.ts
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'; @Injectable() export class ValidationPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } }
src/pipe/validation/validation.pipe.spec.ts
import { ValidationPipe } from './validation.pipe'; describe('ValidationPipe', () => { it('should be defined', () => { expect(new ValidationPipe()).toBeDefined(); }); });
全てのパイプは、PipeTransform
インターフェースを満たすために、transform()
メソッドを実装する必要があります。
value
とmetadata
の2つの引数があり、value
は現在処理されているメソッドの引数で、metadata
は現在処理されているメソッド引数のメタデータです。
メタデータには以下の値があります。
export interface ArgumentMetadata { type: 'body' | 'query' | 'param' | 'custom'; metatype?: Type<unknown>; data?: string; }
type
- 引数が、
@Body()
、@Query()
、@Param()
、またはカスタムパラメータのいずれかを示しています。
- 引数が、
metatype
- 引数のメタタイプを提供します。
data
- デコレータに渡される文字列です。
まとめ
ここまでで、
- パイプについて
- 組み込みパイプについて
- パイプをバインドする方法について
- カスタムパイプについて
を学びました。
次回も、パイプについて掘り下げていこうと思います。
コード
今回のコードは、以下に格納しました。