【问题标题】:Do GraphQL enum types resolve their values automatically?GraphQL 枚举类型会自动解析它们的值吗?
【发布时间】: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];

【问题讨论】:

    标签: graphql


    【解决方案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,
            },
          },
        })
        

        【讨论】:

        【解决方案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

        【讨论】:

          猜你喜欢
          • 2018-04-08
          • 2019-01-07
          • 2017-12-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-02
          • 2015-08-12
          • 1970-01-01
          相关资源
          最近更新 更多