nestjs 中使用 class-validator

4,117 阅读2分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战

class-validator

在 NestJs 框架中提供了几个开箱即用的数据验证的管道。其中ValidationPipe 使用了功能强大的 class-validator 包及其声明性验证装饰器。它提供了一种对所有传入的客户端有效负载强制执行验证规则的便捷方法,其中在每个模块的本地类或者 DTO 声明中使用简单的注释声明特定的规则。

安装

  • 首先安装依赖:
npm i --save class-validator class-transformer
或者
yarn add class-validator class-transformer
  • 验证接口传递的任何数据是一种最佳实践。为了自动保护所有的接口不受不正确数据的影响,我们将ValidationPipe用在整个应用程序中。在启动方法中加入全局管道:
 app.useGlobalPipes(new ValidationPipe());

使用

1、创建一个DTO 文件其中含有 UserDto 类

import { IsNotEmpty } from "class-validator";
​
export class UserDto {
    @IsNotEmpty({ message: 'name 不允许为空' })
    name: string;
​
    @IsNotEmpty({ message: 'code 不允许为空' })
    code: string;
}

2、某个接口的传参使用的 UserDto 类

@Controller('/api/v1')
@UseFilters(ApiExceptionFilter)
export class UserController {   
  
@Post('/user')
    async createUser(
        @Request() req,
        @Body() body: UserDto
    ) {
        const { name, code } = body;
        console.log(name, code);
        return { code: 200, message: 'success' }
    }
}

异常捕获

UserController 使用了异常拦截器 ApiExceptionFilter。在最外层进行异常捕获,然后处理异常。通过 debug 的方式捕获到exception异常

// 以下内容是经过处理的
{
  message:'Bad Request Exception'
  name:'BadRequestException'
  response:{
     error:'Bad Request'
     message:(2) ['name 不允许为空', 'code 不允许为空']
     statusCode:400
    }
  status:400
}

可以看到当没有传2个参数的时候,自定义的错误信息是在response.message数据中。如果试着只对name 进行传值时,message是否还是个数组。实践一下:

03-error.png

可以看到自定义的数据都将在message里显示,所以我们可以对这部分的异常进行特殊处理,错误信息从response.message中获取。

以上是将其作为接口数据校验的方式使用,还可以将其在创建实体类时,对实体类进行属性校验,这样在进行create 操作时避免一些非法脏数据出现。

实体类属性校验

export class UserEntity {
  @Length(10, 20)
  title: string;
​
  @IsPhoneName('US')
  phone: string;
​
  @IsInt()
  @Min(0)
  @Max(10)
  rating: number;
​
  @IsEmail()
  email: string;
​
  @IsDate()
  createDate: Date;
}
​
​
let user = new UserEntity();
user.title = 'Hello'; // 不通过
user.phone = '11233'; // 不通过
user.email = 'google.com'; //不通过validate(user).then(errors => {
  // errors is an array of validation errors
  if (errors.length > 0) {
    console.log('校验失败,错误原因: ', errors);
  } else {
    console.log('校验成功');
  }
​

校验方法返回的是一个ValidationError数组对象,每个ValidationError对象是:

{
    target: Object; // 被校验的对象
    property: string; // .
    value: any; //未通过校验的值
    constraints?: { //使用错误消息进行验证失败的限制。
        [type: string]: string;
    };
    children?: ValidationError[]; // 包含该属性的所有嵌套验证错误
}

\