前回
クラスバリデータを用いたパイプ
Nestは、class-validatorライブラリと連携することができます。
このライブラリを使用すると、デコレータベースのバリデーションを使用できます。
ライブラリをインストールします。
$ npm install --save class-validator class-transformer
インストールしたら、dtoにデコレータを追加します。
src/dto/cat/cat.dto.ts
import { IsInt, IsString } from "class-validator"; export class CreateCatDto { @IsString() name: string; @IsInt() age: number; @IsString() breed: string; }
パイプを修正しましょう。
src/pipe/validation/validation.pipe.ts
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from '@nestjs/common'; import { plainToInstance } from 'class-transformer'; import { validate } from 'class-validator'; @Injectable() export class ValidationPipe implements PipeTransform { private toValidate(metatype: Function): boolean { const types: Function[] = [String, Boolean, Number, Array, Object]; return !types.includes(metatype); } async transform(value: any, {metatype}: ArgumentMetadata) { if (!metatype || !this.toValidate(metatype)) { return value; } const object = plainToInstance(metatype, value); const errors = await validate(object); if (errors.length > 0) { throw new BadRequestException('Validation failed.'); } return value; } }
まず、transform
をasync
にしました。
次に、ArgumentMetadata
から、metatype
を取り出します。
そして、validateできるtypeかどうかを確認します。
その後、plainToInstance
を使用して、型付きオブジェクトに変更し、validateが実行可能なように修正します。
最後に、validate
を実施して、エラーを返すか、値をそのまま返します。
コントローラに適用してみましょう。
src/cats/cats.controller.ts
import { Body, Controller, Get, Post } from '@nestjs/common'; import { CreateCatDto } from 'src/dto/cat/cat.dto'; import { Cat } from './cats.interface'; import { CatsService } from './cats.service'; import { ValidationPipe } from '../pipe/validation/validation.pipe'; @Controller('cats') export class CatsController { constructor(private catsService: CatsService) {} @Post() create(@Body(new ValidationPipe()) createCatDto: CreateCatDto) { this.catsService.create(createCatDto); } @Get() findAll(): Cat[] { return this.catsService.findAll(); } }
@Body
に引数としてnew ValidationPipe()
を渡しました。
まとめ
ここまでで、
- クラスバリデータを用いたパイプについて
を学びました。
次回は、Guardsについて掘り下げようと思います。
コード
今回のコードは、以下に格納しました。