本文介绍了在 NestJS 中使用与 GraphQL 中的 Input 和 Object 类型相同的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置我的 graphql resover 以处理一组对象,但无法配置 @Args 装饰器.

I am trying to setup my graphql resover to handle an array of objects but cant get the @Args decorator configured.

我创建了自己的 ArgsType

I created my own ArgsType

import { ArgsType, Field, Int, ObjectType } from '@nestjs/graphql';

@ArgsType()  // to be used as type in the resolver
@ObjectType()  // for schema generation 
export class Club {
 @Field(type => String)
 president: string;

 @Field(type => Int)
 members?: number;
}

添加单个俱乐部的解析器工作正常!

Resolver with adding a single Club works just fine!

 @Query(() => Int)
 async addClub(@Args() club: Club) {
  // handle stuff
  }

但是如果我想给这样的 Club 数组

but if I want to give an array of Club like this

 @Query(() => Int)
   async addClubs(@Args({name: 'clubs', type: () => [Club]}) clubs: Array<Club>) {
   // handle stuff
  }

这在 Nest 启动时出现错误

this thows an error when nest is starting up

 UnhandledPromiseRejectionWarning: Error: Cannot determine a GraphQL input type for the "clubs". Make sure your class is decorated with an appropriate decorator.

虽然我可以使用这样的字符串数组

although I am able to use an array of Strings like this

 @Query(() => [String])
 async addStrings(@Args({ name: 'clubs', type: () => [String], }) clubs: Array<string>) {
  // handle stuff
  }

我很确定应该有一个简单的解决方案,但不知道从哪里开始.

I am pretty sure there should be an easy solution, but cant figure out where to go from here.

推荐答案

根据错误,

Cannot determine a GraphQL input type for the "clubs". Make sure your class is decorated with an appropriate decorator

您正在尝试使用 Club 类作为 GraphQL 输入类型,而它已经是一个对象类型(根据您使用的 @ObjectType 注释).

You're trying to use Club class as a GraphQL input type while it is already an object type (According to @ObjectType annotation you use).

解决方案 1:

我建议您编写一个单独的 GraphQL 输入类型,如下所示(未测试).如果您需要分离处理 Club 的输入和输出的方式,这会更清晰且耦合更少.

I would suggest you write a separate GraphQL input type like below (not tested). This is cleaner and less coupled if you need to separate the way you treat input and output of Club.

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class ClubInput {
 @Field()
 president: string;

 @Field()
 members?: number;
}

然后在您的解析器中,您可以像下面那样使用它.

Then in your resolver, you can use it like below.

@Query(() => Int)
async addClubs(@Args({name: 'clubs', type: () => [ClubInput]}) clubs: Array<ClubInput>) {
 // handle stuff
}


解决方案 2:

但如果您真的需要为这两个目的使用同一个类,您可以尝试使用相同的 Club 名称创建输入和对象类型.默认情况下,对象类型的名称是类的名称.因此您需要明确提供名称以避免冲突.

But if you really need to use the same class for both purposes, you could try to create both input and object types with the same Club name. The name of the object type is by default the name of the class. So you need to provide the name explicitly to avoid conflict.

import { Field, Int, ObjectType, InputType } from '@nestjs/graphql';

@InputType("ClubInput")
@ObjectType("ClubType")
export class Club {
 @Field(type => String)
 president: string;

 @Field(type => Int)
 members?: number;
}

现在您的 Club 具有不同的输入和对象类型名称.然后在你的解析器中,你可以像下面一样使用它.

Now your Club has different names for input and object types. Then in your resolver, you can use it like below.

@Query(() => Int)
async addClubs(@Args({name: 'clubs', type: () => [ClubInput]}) clubs: Array<ClubInput>) {
 // handle stuff
}

注意:在此解决方案中,您需要确保 Club 永远不会包含表示循环引用或对接口和联合的引用的字段.如果发生这种情况,您将不得不转到解决方案 1,否则这将使您的输入出错.

Note: In this solution, you need to make sure that Club will never contain fields that express circular references or references to interfaces and unions. If that is going to happen, you will have to move to Solution 1, else this will make your input throw an error.

需要注意的是,在 Typescript GraphQL 中,InputTypeObjectType 是两个不同的概念,我们需要正确使用它以避免出现任何问题.

The take away is that in Typescript GraphQL, InputType and ObjectType are two different concepts and we need to use it properly to avoid any issues.

这篇关于在 NestJS 中使用与 GraphQL 中的 Input 和 Object 类型相同的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 06:34