如何让 GraphQL 枚举解析字符串

Posted

技术标签:

【中文标题】如何让 GraphQL 枚举解析字符串【英文标题】:How to have GraphQL enum resolve Strings 【发布时间】:2019-08-02 10:57:52 【问题描述】:

以前,我只是将input KeyInput 输入为mode: String!,我希望将类型从字符串更改!到自定义枚举。

我尝试过以下架构:

enum Mode= 
    test
    live


input KeyInput = 
    mode: Mode!


type Key 
    name,
    mode


type Query 
    Keys(input: KeyInput): [Key]

我的查询如下所示:

query
     Keys(input: mode: "test")
        name
     

但是,我收到以下错误:

      "message": "Expected type Mode!, found \"test\"; Did you mean the enum value test?"

是否可以让枚举值解析字符串值?如果我从输入中删除引号,它将起作用。但是,我需要能够继续将模式解析为字符串。

【问题讨论】:

不清楚您所说的“继续将模式解析为字符串”是什么意思。您能否解释一下为什么在查询中省略引号对您来说是个问题? 对不起;如果我要像这样不带引号查询键:Keys(input: mode: test),GraphQL 解析test 将没有问题。但是,我希望它将引号中的test 解析为"test" 【参考方案1】:

来自spec:

GraphQL 有一个常量字面量来表示枚举输入值。 GraphQL 字符串字面量不能被接受为枚举输入,而是引发查询错误。

对于非字符串符号值(例如,EDN)具有不同表示的查询变量传输序列化应该只允许像枚举输入值这样的值。否则,对于大多数不这样做的传输序列化,字符串可能会被解释为具有相同名称的枚举输入值。

换句话说,当使用枚举作为输入时,如果你使用它作为文字值,像这样:

Keys(input:  mode: test ) 
  name

枚举值(在这种情况下为test)不能被引用,这与字符串文字不同,必须用双引号括起来。

另一方面,如果您使用变量来替换枚举值,则将变量的值设置为字符串,就像您设置常规字符串值一样:

Keys(input:  mode: $mode ) 
  name


// in your component...
variables: 
  mode: 'test'

因为 JSON 不包含枚举值的概念,所以每当我们处理 JSON 上下文时(例如,在声明变量时,或者在为我们的请求返回 data 时),枚举值都被简单地序列化为字符串值.

除此之外,如果您使用 Apollo 作为客户端,是否必须包含引号应该是无关紧要的 - 如果您需要替换 mode 输入字段的值,您应该使用变量来执行此操作,在这种情况下(如上所示),无论如何您都将传递一个字符串值。

【讨论】:

完美答案,谢谢!以及指向规范的链接;我没想到那里看,因为我太专注于apollo-server docs。 我希望保持一致的方式让我的graphiql 用户能够使用Stringsenums。例如,如果我将name: String!Mode: enum 放在一起,则查询似乎不一致:Keys(input: name: "Jim", mode: test) 相反,我希望它能够像这样被查询:Keys(input: name: "Jim", mode: "test") 是的,从 API 的现有使用者的角度来看,将字段更改为枚举将是一项重大更改。

以上是关于如何让 GraphQL 枚举解析字符串的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL SDL 枚举类型

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

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

如何在 GraphQL 中返回枚举选项?

将 graphql 枚举映射到 kotlin 枚举

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