在NestJS的GraphQL中使用与Input和Object类型相同的类 [英] Use the same class as Input and Object type in GraphQL in NestJS

查看:90
本文介绍了在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;
}

添加单个Club的解析器效果很好!

Resolver with adding a single Club works just fine!

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

但是如果我想提供这样的俱乐部

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
  }

这会在嵌套启动时引发错误

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中, InputType ObjectType 是两个不同的概念,我们需要正确使用它以避免出现任何问题.

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类型相同的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆