GraphQL 枚举类型会自动解析它们的值吗?

Posted

技术标签:

【中文标题】GraphQL 枚举类型会自动解析它们的值吗?【英文标题】:Do GraphQL enum types resolve their values automatically? 【发布时间】:2019-06-19 10:20:37 【问题描述】:

我应该期望枚举类型自动解析还是只存在限制选项的类型?

给定以下 GraphQL Schema:

type Job 
  description: String!
  status: Status!


enum Status 
  PENDING_REVIEW
  PENDING_APPROVAL
  APPROVED

和一个看起来像这样的查询:

query job 
  description
  status

如果我的数据库返回以下内容:

 "description": "Some irrelevant job description", "status": 1 

我希望 GraphQL 能够返回:

 "description": "Some irrelevant job description", "status": "PENDING_APPROVAL" 

我是否设置错误,或者这种预期行为需要我为 status 编写解析器

const getQuestionStatus = ( status ) => ['PENDING_REVIEW', 'PENDING_APPROVAL', 'APPROVED'][status];

【问题讨论】:

【参考方案1】:

我认为你需要为它实现解析器。

但是,如果您使用Apollo Server,它有一个名为Internal Values 的功能,您可以在其中使用1 作为解析器中的内部值,Apollo Server 将在返回时自动将其映射到PENDING_APPROVAL回应。

【讨论】:

【参考方案2】:

这取决于您实现 GraphQL 的语言。GraphQL 中的枚举类型只是枚举类型,仅此而已。这意味着,例如,您的 APPROVED 枚举类型不会评估为任何内容。这允许开发人员有更多的空间来做他们想做的事。如果您希望枚举映射到整数,则需要如您所述的解析器。

来自GraphQL article 的架构和类型:

请注意,各种语言的 GraphQL 服务实现将有自己的特定于语言的方式来处理枚举。在支持枚举作为一等公民的语言中,实现可能会利用这一点;在像 javascript 这样不支持枚举的语言中,这些值可能在内部映射到一组整数。

【讨论】:

【参考方案3】:

在 GraphQL.js 中,枚举类型中的每个枚举值都可能具有与之关联的值。设置此值是可选的;它默认为值名称的字符串表示形式。也就是说,对于像这样的枚举:

enum ExampleEnum 
  FOO
  BAR

默认情况下,FOO 的值为"FOO"。如果您使用graphql-tools 来构建您的架构(或使用apollo-server,它在后台使用graphql-tools),我们可以在我们的解析器中传递枚举类型的值:

const resolvers = 
  Query: 
    example: () => 11, // field with ExampleEnum type
  ,
  ExampleEnum: 
    FOO: 11,
    BAR: 23,
  ,

完成此操作后,我们可以在解析器中返回定义的值,并将其序列化为适当的 Enum 值。注意:用作参数的枚举也是如此——如果 FOO 作为参数传入,解析器实际上会收到 11 的值。

不提供任何值等同于做:

ExampleEnum: 
  FOO: 'FOO',
  BAR: 'BAR',

还值得注意的是,提供值不会影响枚举值在响应中的显示方式。当执行结果序列化为 JSON 时,枚举值始终显示为与枚举值名称匹配的字符串值(即我们示例中的 "FOO""BAR")。

原版 GraphQL.js 怎么样?

如果您以编程方式定义架构,也可以提供枚举值的值。这是上面例子的等价物:

const ExampleEnumType = new GraphQLEnumType(
  name: 'ExampleEnum',
  values: 
    FOO: 
      value: 11,
    ,
    BAR: 
      value: 23,
    ,
  ,
)

【讨论】:

默认枚举值怎么样?我的测试表明the resolver receives either the enum as a string, or undefined.【参考方案4】:

是的,您需要将枚举值中的解析器写入您需要的任何内容,例如数字,根据apollo-server docs for Internal values。以下是如何在 TypeScript 中执行此操作:

export enum Status 
  DRAFT,
  PENDING,
  APPROVED


const typeDefs = gql`
  enum Status 
    DRAFT
    PENDING
    APPROVED
  

  type Query 
    echo(status: Status!): Int!
  
`;

const resolvers = 
  Status: 
    DRAFT: Status.DRAFT,
    PENDING: Status.PENDING,
    APPROVED: Status.APPROVED
  ,

  Query: 
    echo(_,  status ): String 
      console.log(status);
      return status;
    
  
;

这是Code Sandbox showing automatic enum parsing and return。

请注意,对于作为查询参数的默认枚举值,其行为是可疑的 - the resolver may receive the enum value as a string, or undefined

【讨论】:

以上是关于GraphQL 枚举类型会自动解析它们的值吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 graphql-tools 使用或解析枚举类型?

如果它们来自数据源,如何在 graphql 模式中表示枚举?

如何让 GraphQL 枚举解析字符串

C语言中的枚举类型

在 GraphQL-java 中为 GraphQL 枚举返回不同的值

在 Graphql 中使用枚举作为查询参数