Nest Validator 校验参数

缘起

在Nest Controller 对客户端参数校验并处理同意的异常结果 Message,例如 校验参数 1< name < 100, 响应不同的 Message " 请填写 name 长度 1 ~ 100 之间 !" 等等

  • 蹩脚写法
typescript 复制代码
@Controller('list')
export class ListController {
  @Post()
  addList(@Body() body): any {
    const { name } = body;
    if(name.length > 100) {
			.....
    }
  }
}

可以使用 class-validator 来完成对参数的校验,class-validator

示例

shell 复制代码
npm i --save class-validator class-transformer

or

shell 复制代码
yarn add class-validator class-transformer

class-validator 和 class-transformer 是一个作者,前者提供数据的校验,后者提供对复杂数据结构的类型转换

使用之前我们先定义一个 Dto 例如 dto.ts 👇🏻

typescript 复制代码
class FooBodyDto {
  @IsString()
  @Length(1, 100, {
    message: '请输入1-100长度之间的名称',
  })
  name: string;
}

export { FooBodyDto };

使用这个 dto 来校验我们需要的参数

处理结果 还可以使用 validateOrReject 具体参考文档

typescript 复制代码
@Controller('list')
export class ListController {
  @Post()
  async addList(@Body() body): Promise<any> {
    const { name } = body;
    const post = plainToClass(FooBodyDto, { name });
    const errors = await validate(post);

    if (errors.length > 0) {
      const msgs = [];
      errors.forEach((item) => {
        msgs.push(Object.values(item.constraints)[0]);
      });
      throw new HttpException(String(msgs), 500);
    } else {
      // ...
    }
  }
}

这段代码,使用 plainToClass 来把客户端的参数转换为 validate 需要的类,然后使用 Dto 里面的校验来对我们的参数进行校验,最好返回的 errors 然后我们对里面的校验结果我们自定义的文案也就是 message 进行合并处理最后用HttpException 异常状态 来抛给 客户端。

完整的逻辑我们还需要一个 Res 拦截器来处理这个异常 例如 response-interceptor.interceptor.ts 👇🏻

typescript 复制代码
import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
  BadGatewayException,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

@Injectable()
export class ResponseInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map((data) => {
        return {
          success: true,
          data,
        };
      }),
      catchError((error) => {
        // 处理异常的数据结构
        return throwError(
          () =>
            new BadGatewayException({
              success: false,
              code: 500,
              message: error.message,
            }),
        );
      }),
    );
  }
}

class-validator

class-validator 来校验参数,除了以上直接使用 validate 、validateOrReject 、还可以直接在 body 上校验

class-validator 更多参考文档这里就不做过多赘述

typescript 复制代码
import { Body, Controller, Post, UsePipes, ValidationPipe } from '@nestjs/common';
import { CreateUserDto } from './create-user.dto';

@Controller('users')
export class UsersController {
  @Post()
  @UsePipes(new ValidationPipe())
  create(@Body() createUserDto: CreateUserDto) {
    // 在这里,如果请求体不满足 CreateUserDto 的验证规则,
    // NestJS 将自动返回一个带有错误详情的 400 Bad Request 响应。

    // 如果验证成功,你可以安全地使用 createUserDto
    // ...
  }
}

class-transformer

class-transformer 不仅可以对 dto 的转换 还可以执行参数的转换 例如

class-transformer 更多参考文档这里就不做过多赘述

  • classToPlain & plainToClass 就是实例和对象的相互转化啦
typescript 复制代码
import { classToPlain } from 'class-transformer';

let user = new User();
// ...给 user 赋值...

let plainUser = classToPlain(user);

------- 分割线 -------


import { plainToClass } from 'class-transformer';

let plainUser = { /* ... */ };

let user = plainToClass(User, plainUser);
typescript 复制代码
import { Exclude, Expose, Transform } from 'class-transformer';

@Exclude() 
export class User {
  id: number;

  @Expose()
  name: string;

  @Expose()
  @Transform(value => value.toUpperCase(), { toClassOnly: true })
  email: string;
}
  • @Exclude():此装饰器用于指定不应该被包含在转换过程中的属性。如果你在类的定义中使用了 @Exclude() 装饰器,那么默认情况下将不包含任何属性,只有被 @Expose() 装饰的属性才会被包含。这对于处理敏感信息非常有用,例如,你可能想要在转换用户对象时排除密码字段。

  • @Expose():此装饰器用于指定应该被包含在转换过程中的属性。如果你没有在类的定义中使用 @Exclude() 装饰器,那么默认情况下会包含所有属性,使用 @Expose() 装饰器在这种情况下没有实际效果。然而,如果你使用了 @Exclude(),那么只有被 @Expose() 装饰的属性才会被包含。

  • @Transform()则是对特定属性的转换,如email 就被 toUpperCase 转换为大写

相关推荐
名字越长技术越强13 小时前
Node.js学习
学习·node.js
知识分享小能手15 小时前
JavaScript学习教程,从入门到精通,Ajax与Node.js Web服务器开发全面指南(24)
开发语言·前端·javascript·学习·ajax·node.js·html5
dwqqw17 小时前
opencv图像库编程
前端·webpack·node.js
layman052819 小时前
node.js 实战——(fs模块 知识点学习)
javascript·node.js
本本啊19 小时前
node 启动本地应用程序并设置窗口大小和屏幕显示位置
前端·node.js
全栈派森21 小时前
Next15 + Prisma + Auth5 实战讲解
react.js·node.js·next.js
·薯条大王21 小时前
Node.js 开发用户登录功能(使用mysql实现)
数据库·mysql·node.js
新时代农民工--小明1 天前
从0开始搭建一套工具函数库,发布npm,支持commonjs模块es模块和script引入使用
前端·javascript·typescript·npm·node.js
xx24061 天前
Node.js简介(nvm使用)
node.js
泯泷1 天前
【SHA-2系列】SHA256 前端安全算法 技术实践
javascript·安全·node.js