获取管道元数据
DTO允许我们通过管道验证请求参数是否符合我们的要求,首先我们要获取管道的元数据
- 通过nest g pi login命令为login创建一个管道元数据获取模块
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'; @Injectable() export class LoginPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { console.log(value,metadata) // { name: 'Su Yihang', age: 20 } { metatype: [class CreateLoginDto], type: 'body', data: undefined } return value; } }
- 在controller里注册
@Controller('login') export class LoginController { constructor(private readonly loginService: LoginService) {} @Post() // 直接丢到Body里即可。这行代码可以理解为:将通过Body装饰器取出的内容通过LoginPipe加工,加工后的数据类型必须是CreateLoginDto create(@Body(LoginPipe) createLoginDto: CreateLoginDto) { return this.loginService.create(createLoginDto); } }
接下来用POST请求访问localhost:3000/login即可打印出元数据
DTO验证并在错误时返回信息
import { ArgumentMetadata, HttpException, HttpStatus, Injectable, PipeTransform } from '@nestjs/common'; import { plainToInstance } from 'class-transformer'; import { validate } from 'class-validator'; @Injectable() export class LoginPipe implements PipeTransform { // transform方法的第一个参数是请求参数,第二个是元数据,其中包含CreateLoginDto类 async transform(value: any, metadata: ArgumentMetadata) { console.log(value, metadata); // { name: 'Su Yihang', age: 20 } { metatype: [class CreateLoginDto], type: 'body', data: undefined } // 通过plainToInstance方法将value值反射到metadata.metatype(CreateLoginDto类)上 const DTO = plainToInstance(metadata.metatype, value); console.log(DTO) // CreateLoginDto { name: 'Su Yihang', age: 20 } // validate方法 const errors = await validate(DTO) // validate方法返回错误信息(即请求参数和CreateLoginDto类型限制不符合的部分) if(errors){ // 如果为空则为空数组,否则数组中会包含错误信息 console.log(errors) // 抛出错误信息 throw new HttpException(errors,HttpStatus.BAD_REQUEST) } return value; } }
以上即为DTO验证全过程
nest.js自带的全局DTO验证
无需上面的繁琐过程,直接在main.ts里来两句
// 引入全局管道DTO import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create<NestExpressApplication>(AppModule); // 使用全局管道(记得实例化) app.useGlobalPipes(new ValidationPipe()) await app.listen(3000); } bootstrap();