class-validator 根据父属性验证嵌套对象
class-validator validate nested object based on parent properties
有没有办法根据父对象的属性验证子对象中的字段。以下对象代表我们试图验证的结构。例如在下面的结构中只有 first.name 在定义了 id 和 dateOfBirth (dob) 时不需要?
@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
所有其他都将被视为无效
这是我想出的解决方案,如果有更好的方法请告诉我。
自定义验证器约束
@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';
}
}
资格标准包装器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 class
有没有办法根据父对象的属性验证子对象中的字段。以下对象代表我们试图验证的结构。例如在下面的结构中只有 first.name 在定义了 id 和 dateOfBirth (dob) 时不需要?
@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
所有其他都将被视为无效
这是我想出的解决方案,如果有更好的方法请告诉我。
自定义验证器约束
@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';
}
}
资格标准包装器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 class