【问题标题】:Give support for validation on optional parameter using class-validator in NestJS and GraphQL?是否支持在 NestJS 和 GraphQL 中使用类验证器对可选参数进行验证?
【发布时间】:2020-07-20 14:20:24
【问题描述】:

我有这个input 用于更新块。我希望用户可以更新名称或内容或两者兼而有之。 现在的问题是,如果我只传递名称 GrapQL 会抛出类似 Variable \"$updateBlockInput\" got invalid value { name: \"Updated again\" }; Field content of required type String! was not provided. 和副 varsa 之类的错误。

我做错了什么?


update-block.input.ts

import { InputType, Field } from '@nestjs/graphql';
import { IsOptional, IsNotEmpty } from 'class-validator';

@InputType()
export class UpdateBlockInput {
  @IsOptional()
  @IsNotEmpty()
  @Field()
  name?: string;

  @IsOptional()
  @IsNotEmpty()
  @Field()
  content?: string;
}

block.resolver.ts

...
@Mutation(returns => BlockType)
updateBlock(
  @Args('id') id: string,
  @Args('updateBlockInput') updateBlockInput: UpdateBlockInput,
) {
  return this.blockService.update(id, updateBlockInput);
}
...

变异

mutation(
  $id: String!
  $updateBlockInput: UpdateBlockInput!
) {
  updateBlock(
    id: $id
    updateBlockInput: $updateBlockInput
  ) {
    name
    content
  }
}

变量

{
  "id": "087e7c12-b48f-4ac4-ae76-1b9a96bbcbdc",
  "updateBlockInput": {
    "name": "Updated again"
  }
}

【问题讨论】:

    标签: graphql nest nestjs class-validator


    【解决方案1】:

    如果它们是可选的,那么您需要避免使用 IsNotEmpty 并替换为 IsString 来表示如果值存在,则它必须是字符串类型。

    如果您想接受其中任何一个并且在发送非时失败,您需要编写自己的自定义验证器,因为开箱即用不支持这种情况。

    一个例子:

    import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
    @ValidatorConstraint({async: false})
    export class IsInPast implements ValidatorConstraintInterface {
        public validate(value: unknown): boolean {
            if (typeof value !== 'string' && typeof value !== 'number') {
                return false;
            }
            const now = new Date();
            now.setHours(23);
            now.setMinutes(59);
            now.setSeconds(59);
            now.setMilliseconds(999);
            return `${value}`.match(/^\d+$/) !== null && `${value}` <= `${now.getTime()}`;
        }
    
        public defaultMessage(): string {
            return 'Should be in past';
        }
    }
    

    然后在代码中的某个地方:

    @Validate(IsInPast)
    public dateField: string;
    

    【讨论】:

    • 你能给我一个自定义验证器的例子吗?谢谢。
    • 添加到答案中。
    猜你喜欢
    • 2019-08-29
    • 2021-03-09
    • 2019-05-16
    • 2021-01-29
    • 2021-04-22
    • 2022-08-02
    • 1970-01-01
    • 2021-02-03
    • 2020-08-09
    相关资源
    最近更新 更多