在nestjs项目中,当我们的定义了DTO之后,不代表就可以自动对请求数据进行验证了,我们需要把DTO作为类型提示添加到的参数上,代码如下:
// controller 文件
export class UserController {
@Get()
async userList(
@Query()
options: QueryUserDto
){
return '用户列表'
}
}
加上了DTO之后仍然不能对数据进行校验。
发送请求之后,仍然能够正常响应数据:123
要想使他开始校验,则必须要在Query
,Body
等装饰器上加上ValidationPipe
管道才能对请求数据进行验证
代码如下:
@Get()
@SerializeOptions({ groups: ['post-list'] })
async list(
@Query(
new ValidationPipe({
transform: true,
forbidUnknownValues: true,
validationError: { target: false },
whitelist: true
}),
)
options: QueryPostDto,
) {
console.log(options)
return '用户列表'
}
ValidationPipe的处理步骤
- 先将传进来普通对象通过 class-transformer 包的 plainToClass 函数转化成 dto 类的实例.
- 将得到的这个 dto 实例通过 class-validator 包的 validate 函数进行验证,validate 函数同时会对 dto 实例进行相应处理(比如,设置了 whitelist, 会删除没有被 class-Validator 装饰器装饰的属性)
- 将这个 dto 实例再次通过 class-transformer 包的 classToPlain 函数将 dto 实例转化成普通对象
- controller 方法收到相应参数
具体参数(部分)的作用
可以看到这里传入了3个参数:transform
,forbidUnknownValues
,validationError
,whitelist
-
transform
当设置为true的时候,ValidationPipe 在处理的时候就会跳过第3步。 开启transform之后,会将传入的请求数据转化为以下形式,一个DTO类的实例对象QueryPostDto { test: undefined, aaa: false, bbb: 'xxx', page: 1, limit: 10, id: '123' }
-
forbidUnknownValues
规定了DTO中的至少有一个属性是添加了验证规则装饰器的 -
validationError.target
指示是否应该在ValidationError中公开目标(这个是官方文档的说明)。 -
whitelist
如果设置为true,验证器将剥离已验证(返回)对象中不使用任何验证装饰器的任何属性。 比如在请求的时候我传了一个额外的aaa,处理的时候就会将aaa删除掉QueryPostDto { test: undefined, bbb: 'xxx', page: 1, limit: 10, id: '123' }