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 转换为大写

相关推荐
一个很帅的帅哥11 小时前
实现浏览器的下拉加载功能(类似知乎)
开发语言·javascript·mysql·mongodb·node.js·vue·express
Bang邦14 小时前
使用nvm管理Node.js多版本
前端·node.js·node多版本管理
新知图书15 小时前
Node.js快速入门
node.js
FakeOccupational16 小时前
nodejs 007:错误npm error Error: EPERM: operation not permitted, symlink
前端·npm·node.js
亦舒.16 小时前
JSDelivr & NPM CDN 国内加速节点
前端·npm·node.js
代码搬运媛16 小时前
code eintegrity npm err sha512
前端·npm·node.js
猿来如此呀20 小时前
运行npm install 时,卡在sill idealTree buildDeps没有反应
前端·npm·node.js
八了个戒1 天前
Koa (下一代web框架) 【Node.js进阶】
前端·node.js
谢尔登1 天前
【Node.js】RabbitMQ 不同交换器类型的使用
node.js·rabbitmq·ruby
weixin_441018351 天前
webpack的热更新原理
前端·webpack·node.js