NestJS 管道DTO

81 阅读1分钟

管道是用 @Injectable() 装饰器注释的类,它实现了 PipeTransform 接口。

image.png

管道有两个典型的用例:

  • transformation: 将输入数据转换为所需的形式(例如,从字符串到整数)
  • validation: 评估输入数据,如果有效,只需将其原样传递; 否则抛出异常

内置管道#

Nest 附带九个开箱即用的管道:

  • ValidationPipe
  • ParseIntPipe
  • ParseFloatPipe
  • ParseBoolPipe
  • ParseArrayPipe
  • ParseUUIDPipe
  • ParseEnumPipe
  • DefaultValuePipe
  • ParseFilePipe

他们从@nestjs/common导出

例如

想要一个number

@Get(':id')
testPipe(@Param('id') id:string){
    console.log(typeof id)
}

image.png

使用内置管道

  @Get(':id')
  testPipe(@Param('id',ParseIntPipe) id:number){
    console.log(typeof id)
  }

image.png

类验证器
yarn add class-validator class-transformer -S
nest --help

image.png

执行

nest g pi demopipe

image.png

demo.pipe.ts

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException, HttpStatus } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class DemoPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    console.log(value,metatype)
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException(errors);
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}

create.demo.dto.ts


import { IsString, IsInt,Length, IsEmpty } from 'class-validator';

export class CreateDemoDto {
    @IsString()
    @IsEmpty({
        message:"不能为空"
    })
    @Length(2,10,{
        message:"长度在2-10之间"
    })
    name:string
    @IsInt()
    age:number
}

使用 demo.controller.ts

  @Post('pipe')
  execPipe(@Body(DemoPipe) CreateDemoDto:CreateDemoDto){
    console.log("CreateDemoDto",CreateDemoDto)
  }

运行结果 会在message以数组的形式返回

image.png

全局作用域管道
import { ValidationPipe } from '@nestjs/common'
app.useGlobalPipes(new ValidationPipe())

此时 在@Body中不采用 DemoPipe

  @Post('pipe')
  execPipe(@Body() CreateDemoDto:CreateDemoDto){
    console.log("CreateDemoDto",CreateDemoDto)
  }

执行

image.png