Skip to content

Latest commit

 

History

History
110 lines (93 loc) · 3.07 KB

NestJS项目实践.md

File metadata and controls

110 lines (93 loc) · 3.07 KB

NestJS项目实践

使用环境

  1. egg.js版本为3.5.2
  2. NodeJS版本为18.15.0
  3. npm版本为9.5.0
  4. TypeScript版本为4.x

nest/swagger

详细使用请查阅文档nestJS中的主题OpenAPI (Swagger) .

nest/swagger中如何定义一个字段多种类型的接口?

// 普通注册类型
export class AuthDto {
  @ApiProperty({
    description: '用户名',
    minLength: 4,
    maxLength: 20,
  })
  @MinLength(4)
  @MaxLength(20)
  username: string;

  @ApiProperty({
    description: '密码',
  })
  password: string;
}

// 邮件注册类型
export class EmailAuthDto extends OmitType(AuthDto, ['username']) {
  @IsEmail()
  @ApiProperty({
    description: '邮箱',
  })
  email: string;
}

// 手机号注册类型
export class PhoneAuthDto extends OmitType(AuthDto, ['username']) {
  @ApiProperty({
    description: '手机号',
  })
  @IsPhoneNumber()
  phone: string;
}

@ApiExtraModels(AuthDto, EmailAuthDto, PhoneAuthDto) // oneOf 生成文档时,需要引入这三个类
// 注册接口只使用类型 RegisterDto
export class RegisterDto {
  @ApiProperty({
    description: '注册信息',
    oneOf: [
      { $ref: getSchemaPath(AuthDto) },
      { $ref: getSchemaPath(EmailAuthDto) },
      { $ref: getSchemaPath(PhoneAuthDto) },
    ],
  })
  auth: AuthDto | EmailAuthDto | PhoneAuthDto;

  @ApiProperty({
    description: '注册方式',
    enum: RegisterEnum,
  })
  type: RegisterEnum;
}

注册接口只使用类型 RegisterDto,其中RegisterDto中的auth字段包含着可能是AuthDto,EmailAuthDto ,PhoneAuthDto中的一种类型对象,我们需在@ApiProperty中使用oneOf字段进行定义,同时还要注意:

  1. $ref和getSchemaPath(TheClass)配套使用
  2. @ApiExtraModels(class1[ class2 class3 ...])需要引入注册相关类
  3. 类似的还有oneOf, anyOf, allOf

nest/swagger中如何对一个字段可能得多种类型进行参数校验?

原因为nest/swagger无法对嵌套结构中的类型进行校验,所以目前我采用的较好方式为下方法的手动校验.

// 沿用上例类型
import { plainToClass } from 'class-transformer';
import { validate } from 'class-validator';
// ...
@Post('register')
async register(registerDto: RegisterDto) {
    let errors: ValidationError[] = [];
    switch (registerDto.type) {
      case RegisterEnum.NORMAL:
        auth = plainToClass(AuthDto, registerDto.auth);
        errors = await validate(auth);
        console.log(auth, errors);
        if (errors.length) {
          throw new Error(
            errors
              .map((error) => {
                return Object.values(error.constraints).join(',');
              })
              .join('\n'),
          );
        }
        return 'normal';
      // ...
    }

使用class-transformer中的plainToClassclass-validator中的validate配套校验,如果validate返回了错误数组,则参数校验失败,我们按流程将校验失败结果告知用户即可.