【问题标题】:How to change validation in nested object using same class in NestJS如何使用 NestJS 中的同一类更改嵌套对象中的验证
【发布时间】:2021-07-11 11:11:58
【问题描述】:

我有一个前端应用程序,它向我的后端应用程序发送一个带有以下 JSON 正文的 POST 请求

{
    "principal": {
        "name": "John Doe",
        "birth": "1990-01-01T02:00:00.000Z",
        "phone": "(12) 341 234 124",
        "email": "test@test.com"
    },
    "companion": {
        "name": "",
        "birth": null,
        "phone": "",
        "email": ""
    },
    ... // some other data
}

在我使用 NestJS 的后端应用程序中,由于 principalcompanion 具有相同的属性,我映射到以下 DTO。

import { IsNotEmpty, IsString } from "class-validator";

export class NewDataDto {
    principal: PersonDto;
    companion: PersonDto;
    // some other data
}

export class PersonDto {
    @IsNotEmpty()
    @IsString()
    name: string;

    birth?: Date;

    @IsNotEmpty()
    @IsString()
    phone: string;

    @IsNotEmpty()
    @IsString()
    email: string;
} 

所以在principal 对象中,所有属性都是必需的,但在companion 对象中,所有属性都是可选的。由于两个对象的所有属性都相同,只有验证发生了变化,如何验证对两个对象使用相同的类?

【问题讨论】:

  • 是的,我试过了。但是我有 2 个具有不同验证的对象属于同一类,因此 name 必须在 principal 中是必需的,但在 companion 中可以为空。
  • 为验证目的创建单独的类怎么样?
  • 是的,我同意 Bruno 的观点,即最好将班级分开。并查看来自 Nest js docs.nestjs.com/openapi/mapped-types 的映射类型包
  • 是的,这是一种解决方法。但是如此严重地违反了DRY 原则,以至于让我无法遵循这个解决方案。

标签: typescript nestjs class-validator


【解决方案1】:

所以我找到了问题的答案。确实有办法做到这一点。不使用同一个类,但不损害 DRY 原则和重用代码。我会把它贴在这里,所以它可以使有同样问题的人受益。

export class PersonDto {
    protected validateRequiredFields = false;
    
    @ValidateIf((o) => o.validateRequiredFields || o.name)
    @IsNotEmpty()
    @IsString()
    name: string;

    birth?: Date;

    @ValidateIf((o) => o.validateRequiredFields || o.phone)
    @IsNotEmpty()
    @IsString()
    phone: string;

    @ValidateIf((o) => o.validateRequiredFields || o.email)
    @IsNotEmpty()
    @IsString()
    email: string;
}

export class PrincipalDto extends PersonDto{
    constructor() {
        super();
        this.validateRequiredFields = true;
    }
}

export class NewDataDto {
    @ValidateNested()
    @Type(() => PrincipalDto)
    @IsDefined()
    principal: PrincipalDto;

    @ValidateNested()
    @Type(() => PersonDto)
    companion: PersonDto;

    // some other data
} 

这里有一些注意事项。

首先,如果所有类都在同一个文件中,则需要先声明没有依赖关系的类。

其次,在@ValidateIf 中,您需要将validateRequiredFields 与 OR 子句和您正在验证的字段一起放入,因为您想验证该字段是否具有某些值。

第三,在验证母类时,在我的例子中是NewDataDto,确保你正确地验证了@Type。并将@IsDefined 放在您希望验证必填字段的属性中。

最后,您可以在构造函数内部或外部覆盖validateRequiredFields,并且在子类中没有构造函数,它会正常工作。但我个人喜欢构造函数思想中的覆盖。

【讨论】:

    猜你喜欢
    • 2021-04-22
    • 2019-05-16
    • 2021-05-05
    • 2020-06-05
    • 2021-03-09
    • 2021-08-10
    • 1970-01-01
    • 2019-05-08
    相关资源
    最近更新 更多