【问题标题】:class-validator validate nested object based on parent properties类验证器根据父属性验证嵌套对象
【发布时间】:2020-12-02 13:47:41
【问题描述】:

有没有办法根据父对象的属性验证子对象中的字段。以下对象代表我们试图验证的结构。例如,在下面的结构中,定义 id 和 dateOfBirth (dob) 时只需要 first.name 吗?

@InputType()
export class GetEligibilityArgs {       
  @Field((type) => NameInput)
  @ValidateNested()
  @Type(() => NameInput)
  name: NameInput;
 
  @Field({ nullable: true })
  @ValidateIf((o: GetEligibilityArgs) => {
    return !(o.name?.first && o.name?.last && o.dateOfBirth);
  })
  @IsNotEmpty({ message: 'id is required' })
  id?: string;

  @Field({ nullable: true })
  @ValidateIf((o: GetEligibilityArgs) => {   // <-- not sure if this is the correct way to do this
    return !(o.id && o.name?.first && o.name?.last);
  })
  @IsNotEmpty()
  dateOfBirth?: string;
}

嵌套对象

@InputType()
export class NameInput {
  @Field({ nullable: true })
  @IsNotEmpty()
  first?: string;

  @Field({ nullable: true })
  @IsNotEmpty()
  last?: string;
}

有效输入

  • id、name.first、name.last
  • id, name.first, dob
  • id, name.last, dob
  • name.first, name.last, dob

所有其他都将被视为无效

【问题讨论】:

  • 自定义验证器或验证组是否适用于此?我正在考虑整个对象或名称字段上的自定义验证器。另一种选择是对 4 个有效案例使用 4 个验证组
  • @Nikolay 谢谢,我是类验证器的新手,我会在谷歌上搜索这些选项。如果您有指向您提到的任何内容的示例的链接,那就太好了
  • 实现验证组有点棘手,这取决于您是否使用global validation pipe,因为那样您将无法在控制器级别应用验证组 - 请参阅this issue

标签: typescript graphql nestjs class-validator


【解决方案1】:

这是我想出的解决方案,如果有更好的方法,请告诉我。

自定义验证器约束

@ValidatorConstraint()
export class GetEligibilityCriteriaConstraint implements ValidatorConstraintInterface {
  validate(
    { id, name, dateOfBirth }: GetEligibilityArgs,
    validationArguments: ValidationArguments,
  ) {
    if (id && name?.first && name?.last) {
      return true;
    }
    if (id && name?.first && dateOfBirth) {
      return true;
    }
    if (id && name?.last && dateOfBirth) {
      return true;
    }
    if (name?.first && name?.last && dateOfBirth) {
      return true;
    }
    return false;
  }

  defaultMessage(args: ValidationArguments) {
    return 'Eligibility requires 3 of the following 4 fields (id, name.first, name.last, dateOfBirth';
  }
}

Eligibility Criteria Wrapper Class 用于验证对象

@ArgsType()
export class GetEligibilityCriteria {
  @Field((type) => GetEligibilityArgs)
  @Validate(GetEligibilityCriteriaConstraint)
  @Type(() => GetEligibilityArgs)
  @ValidateNested()
  criteria: GetEligibilityArgs;
}

然后像这样在解析器查询中使用它

 @Query((returns) => Eligibility)
  eligibility(@Args() { criteria }: GetEligibilityCriteria) {
    // performs some mapping and calls service 
  }

标准验证器约束应用于 GetEligibilityArgs 类

【讨论】:

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