如何在 GraphQL 类型中引用特定的 ENUM 值?
Posted
技术标签:
【中文标题】如何在 GraphQL 类型中引用特定的 ENUM 值?【英文标题】:How to reference a specific ENUM value in GraphQL type? 【发布时间】:2017-11-11 13:11:34 【问题描述】:我有以下架构:
enum PaymentTypeName
PAYMENT_CARD
PAYMENT_CARD_TOKEN
interface Payment
id: ID!
type: PaymentTypeName!
type PaymentCardPayment implements Payment
id: ID!
type: PaymentTypeName!
card: PaymentCard!
type PaymentCardTokenPayment implements Payment
id: ID!
type: PaymentTypeName!
card: PaymentCard!
当Payment
为PaymentCardPayment
或PaymentCardTokenPayment
时,由type 的值决定,即为PAYMENT_CARD
或PAYMENT_CARD_TOKEN
。
如何在界面中表示PaymentCardPayment
/PaymentCardTokenPayment
继承了PaymentTypeName
的特定值?
我尝试了以下各种组合:
type PaymentCardPayment implements Payment
id: ID!
type: PaymentTypeName.PAYMENT_CARD!
card: PaymentCard!
和:
type PaymentCardPayment implements Payment
id: ID!
type: PaymentTypeName[PAYMENT_CARD]!
card: PaymentCard!
但所有这些都提示语法错误,我无法找到相关文档。
【问题讨论】:
你找到解决办法了吗? 【参考方案1】:您正试图在您的类型架构中声明字段 value,这不是架构的用途。你应该只在你的模式中声明你的字段type,在这种情况下它只是type: PaymentTypeName
。您在第一个代码块中已正确。
您的PaymentCardPayment
的type
解析器函数应返回枚举的值,在您的情况下为PAYMENT_CARD
。
您的PaymentCardTokenPayment
的type
解析器函数应返回PAYMENT_CARD_TOKEN
的值。
【讨论】:
我不同意。 ENUM 是一个特例。PaymentType
上下文 type
可以继承任何 PaymentTypeName
值是有道理的。但是,在 PaymentCardPayment
的上下文中,说该值是 ENUM 值中的一个是误导性的;它不是。它是一个常量值,它是PaymentTypeName
的子集。
必须同意,细化子集将始终是来自ENUM
的静态值,接口保证是有意义的,并且可能是ENUM
在不使用时使用的常见方式之一用于通过输入类型进行过滤。
那么您找到解决方案了吗?【参考方案2】:
使用默认值对你有用吗?
type PaymentCardPayment implements Payment
id: ID!
type: PaymentTypeName! = PAYMENT_CARD
card: PaymentCard!
它不会阻止您覆盖该值,但至少应该正确设置它。
【讨论】:
这会很棒。但我得到一个语法错误 - 你确定这有效吗?【参考方案3】:GraphQL 不支持您尝试执行的操作。如果一个字段的类型被声明为PaymentTypeName
,并且PAYMENT_CARD
和PAYMENT_CARD_TOKEN
都是PaymentTypeName
的有效值,那么它们也必须是该字段的有效值。无法获取现有类型(无论是枚举、标量还是对象类型)并有条件地从该类型已定义的可能值集中创建可能值的子集。
也就是说,如果PaymentCardPayment.type
将始终解析为PAYMENT_CARD
并且PaymentCardTokenPayment.type
将始终解析为PAYMENT_CARD_TOKEN
,那么在这里使用枚举根本没有意义。实际上,在这种特定情况下,我们可以完全省略 type
字段。毕竟,在这种情况下,该字段的唯一目的是允许客户端区分Payment
可能解析为的可能类型。但是,GraphQL 已经为我们提供了一个 __typename 字段,它通过解析为已解析类型的名称来做到这一点。
所以在这个特定的例子中,这样做就足够了:
interface Payment
id: ID!
type PaymentCardPayment implements Payment
id: ID!
card: PaymentCard!
type PaymentCardTokenPayment implements Payment
id: ID!
card: PaymentCard!
并像这样查询类型为Payment
的字段:
payments
id
__typename
... on PaymentCardPayment
card
# ...
... on PaymentCardTokenPayment
card
# ...
【讨论】:
以上是关于如何在 GraphQL 类型中引用特定的 ENUM 值?的主要内容,如果未能解决你的问题,请参考以下文章
GraphQL & Mongoose Schema - 如何将一组 mongoose objectId 引用存储到另一种类型?