之前 pipe 来对参数做验证和转换,都是 get 请求的参数,如果是 post 请求怎么做?
post 请求的数据是通过 @Body 装饰器来取,并且要有一个 dto class 来接收
(dto 是 data transfer object,数据传输对象,用于封装请求体的数据)
结果
如果传递 浮点数据 还是可以
要对他做参数验证,使用 ValidationPipe
需要
npm install class-validator class-transformer
它属于 Pipe(管道) ,执行时机是:
Middleware
→ Guard
→ Pipe 👈(这里)
→ Interceptor(before)
→ Controller handler
→ Interceptor(after)
→ ExceptionFilter
也就是说:
Controller 方法真正执行之前,ValidationPipe 就已经跑完了
ValidationPipe 源码
export class ValidationPipe implements PipeTransform {
async transform(value, metadata) {
const { metatype } = metadata;
// 1. 是否需要校验
if (!this.toValidate(metadata)) {
return value;
}
// 2. plain -> class
const object = plainToInstance(metatype, value);
// 3. 校验
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException(errors);
}
// 4. 返回
return this.transform ? object : value;
}
}
pipe 里也是可以注入依赖的
新增 my-validation-pipe.ts
import {
PipeTransform,
Injectable,
ArgumentMetadata,
BadRequestException,
Optional,
Inject,
} from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';
@Injectable()
export class MyValidationPipe implements PipeTransform<any> {
@Optional()
@Inject('validation_options')
private options: any;
async transform(value: any, { metatype }: ArgumentMetadata) {
if (!metatype) {
return value;
}
console.log(this.options);
const object = plainToInstance(metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException('参数验证失败');
}
return value;
}
}
可以正常注入
没有注入什么依赖,所以这种方式也可以
全局这样写
class-validator 都支持哪些验证方式
声明这样一个 ppp.dto.ts class
import {
Contains,
IsDate,
IsEmail,
IsFQDN,
IsInt,
Length,
Max,
Min,
} from 'class-validator';
export class Ppp {
@Length(10, 20)
title: string;
@Contains('hello')
text: string;
@IsInt()
@Min(0)
@Max(10)
rating: number;
@IsEmail()
email: string;
@IsFQDN()
site: string;
}
使用
传递正常数据不报错
错误消息可修改