首页 > 解决方案 > 如何使用 GraphQL 在 NestJS 中创建自定义字段验证装饰器

问题描述

我正在使用 apollo-server-express 开发 NestJS API,并且我有下一个 InputType 用于约会:

@InputType()
export class AppointmentInput {
    @Field(of => String)
    @IsNotEmpty()
    name: string;

    @Field(of => String)
    @IsNotEmpty()
    @IsDateString()
    dateStart: string;

    @Field(of => String)
    @IsNotEmpty()
    @IsDateString()
    dateEnd: string;

    @Field(of => Boolean)
    @IsBoolean()
    paid: boolean;

    @Field(of => Int)
    idDoctor: number;
    
    @Field(of => Int)
    idPatient: number;
    @Field(of => Int)
    idService: number;
}

假设我想验证名称是否有一些带有管道的“a”字母:

import { PipeTransform, Injectable, ArgumentMetadata, HttpException, HttpStatus } from '@nestjs/common';

@Injectable()
export class NamePipe implements PipeTransform<string, string>{
  transform(name: string, metadata: ArgumentMetadata) {
    if (name.includes('a')) {
      throw new HttpException('The name has an a', HttpStatus.BAD_REQUEST);
    }
    return name;
  }
}

但是如果像这样使用它:

@Field(of => String)
@IsNotEmpty()
@UsePipes(NamePipe)
name: string;

它向我抛出了下一个错误:

属性装饰器函数的返回类型必须是“void”或“any”。当作为表达式调用时,无法解析属性装饰器的签名。类型“TypedPropertyDescriptor”不可分配给类型“void”。

我该如何解决这个问题并使用自定义装饰器来验证我的字段?我的装饰器可以调用服务也很重要,因为将来我可能想验证角色 id,并检查数据库中是否存在具有该 id 的角色,如果没有则抛出错误。

标签: typescriptgraphqlnestjsapollo-server

解决方案


我认为你应该创建一个自定义的类验证器装饰器,并像使用任何类验证器装饰器一样使用它,假设你已经应用了一个全局 NestJS 验证管道


推荐阅读