如何在GraphQL类型中引用特定的ENUM值?

Gaj*_*jus 5 graphql graphql-js

我有以下架构:

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!
}
Run Code Online (Sandbox Code Playgroud)

什么时候PaymentPaymentCardPaymentPaymentCardTokenPayment由类型的值决定,即它是PAYMENT_CARDPAYMENT_CARD_TOKEN

我如何在界面中表示PaymentCardPayment/ PaymentCardTokenPayment继承特定值PaymentTypeName

我尝试了以下各种组合:

type PaymentCardPayment implements Payment {
  id: ID!
  type: PaymentTypeName.PAYMENT_CARD!
  card: PaymentCard!
}
Run Code Online (Sandbox Code Playgroud)

和:

type PaymentCardPayment implements Payment {
  id: ID!
  type: PaymentTypeName[PAYMENT_CARD]!
  card: PaymentCard!
}
Run Code Online (Sandbox Code Playgroud)

但是所有这些提示语法错误,而我找不到相关的文档。

Dan*_*den 5

GraphQL 不支持您尝试执行的操作。如果字段的类型声明为PaymentTypeName、 、PAYMENT_CARDPAYMENT_CARD_TOKEN都是 的有效值PaymentTypeName,那么它们也必须是该字段的有效值。无法采用现有类型(无论是枚举、标量还是对象类型)并有条件地从该类型已定义的可能值集中创建可能值的子集。

也就是说,如果PaymentCardPayment.typewill 始终解析为PAYMENT_CARDPaymentCardTokenPayment.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!
}
Run Code Online (Sandbox Code Playgroud)

并查询一个类型如下的字段Payment

{
  payments {
    id
    __typename
    ... on PaymentCardPayment {
      card {
        # ...
      }
    }
    ... on PaymentCardTokenPayment {
      card {
        # ...
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 2

您试图在类型架构中声明字段,这不是架构的用途。您应该只在架构中声明您的字段类型,在本例中它只是type: PaymentTypeName. 您的第一个代码块中的内容是正确的。

您的PaymentCardPayment解析器type函数应该返回枚举的值,在您的情况下,PAYMENT_CARD.

您的PaymentCardTokenPayment解析器type函数应该返回 的值PAYMENT_CARD_TOKEN

  • 我不同意。ENUM 是一种特殊情况。在“PaymentType”上下文中,“type”可以继承任何“PaymentTypeName”值是有意义的。然而,在“PaymentCardPayment”的上下文中,说该值是 ENUM 值之一是有误导性的;它不是。它是一个常量值,是“PaymentTypeName”的子集。 (3认同)
  • 必须同意,细化子集将始终是接口保证的“ENUM”的静态值,并且可能是“ENUM”在不用于通过输入类型进行过滤时使用的常见方式之一。 (3认同)