如何使用 NestJS 中的相同类更改嵌套对象中的验证 [英] How to change validation in nested object using same class in NestJS

查看:88
本文介绍了如何使用 NestJS 中的相同类更改嵌套对象中的验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a frontend application which sends to my backend application a POST request with the following JSON body

{
    "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.

And in my backend application, which I'm using NestJS, since both, principal and companion have the same properties, I mapped to the following 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对象中,所有的属性都是可选的.由于两个对象中的所有属性都相同,只有验证发生了变化,我如何对两个对象使用相同的类来验证?

So in the principal object, all the properties are required, but in the companion object, all properties are optional. Since all the properties are the same in both objects, only the validation changes, how do I validate that using the same class to both objects?

推荐答案

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

So I found an answer to my problem. There is indeed a way to do it. Not using the same class, but not hurting the DRY principals and reusing code. I will post it here, so it could benefit someone that has the same issue.

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
} 

这里有一些注意事项.

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

First, if all the classes are in the same file, you need to declare the classes that has no dependency first.

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

Second, in the @ValidateIf you need to put the validateRequiredFields with an OR clause and the field that you are validating, because you want to validate if the field has some value.

第三,在验证母类时,在我的例子中是 NewDataDto,请确保您正确验证了 @Type.并在您希望验证必填字段的属性中放置一个 @IsDefined.

Third, when validating the mother class, in my case NewDataDto, make sure you are validating @Type correctly. And put a @IsDefined in the property you want the required fields to be validated.

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

And last, you can override the validateRequiredFields inside the constructor or outside and don't have a constructor in the subclass, and it will work just fine. But I personally like the override in the constructor idea.

这篇关于如何使用 NestJS 中的相同类更改嵌套对象中的验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆