graphql,联合标量类型?

Posted

技术标签:

【中文标题】graphql,联合标量类型?【英文标题】:graphql, union scalar type? 【发布时间】:2018-09-28 13:18:55 【问题描述】:

payload 字段可以是 IntString 标量类型。 当我把它写成联合类型时:

const schema = `
  input QuickReply 
    content_type: String
    title: String
    payload: Int | String
    image_url: String
  
`

我遇到了一个错误:

GraphQLError: Syntax Error GraphQL request (45:18) Expected Name, found |

    44:     title: String
    45:     payload: Int | String
                         ^
    46:     image_url: String

看来GraphQL 不支持联合标量类型。

那么,我该如何解决这种情况呢?

【问题讨论】:

【参考方案1】:

标量不能用作联合的一部分,因为根据规范,联合专门“表示可能是 GraphQL 对象类型列表之一的对象”。相反,您可以使用自定义标量。例如:

const MAX_INT = 2147483647
const MIN_INT = -2147483648
const coerceIntString = (value) => 
  if (Array.isArray(value)) 
    throw new TypeError(`IntString cannot represent an array value: [$String(value)]`)
  
  if (Number.isInteger(value)) 
    if (value < MIN_INT || value > MAX_INT) 
      throw new TypeError(`Value is integer but outside of valid range for 32-bit signed integer: $String(value)`)
    
    return value
  
  return String(value)

const IntString = new GraphQLScalarType(
  name: 'IntString',
  serialize: coerceIntString,
  parseValue: coerceIntString,
  parseLiteral(ast) 
    if (ast.kind === Kind.INT) 
      return coerceIntString(parseInt(ast.value, 10))
    
    if (ast.kind === Kind.STRING) 
      return ast.value
    
    return undefined
  
)

此代码有效地结合了 Int 和 String 类型的行为,同时仍然强制 32 位有符号整数的范围。但是,您可以拥有任何类型的强制行为。查看the source code 了解内置标量如何工作,或查看this article 了解有关自定义标量如何工作的更多详细信息。

请注意,如果您尝试为 output 字段返回多个标量之一,则可以使用 parent 类型的联合来获得类似的结果.例如,这是不可能的:

type Post 
  content: String | Int

但您可以执行以下操作:

type PostString 
  content: String


type PostInt 
  content: Int


union Post = PostString | PostInt

【讨论】:

超级有趣的答案!!!我在其他任何地方都找不到这样一个相关的例子...... 这听起来像是混合多个标量的好解决方案。在我的例子中,有一个任务的响应,它可能是标量(Int,String)或对象类型。我可以使用标量 JSON 代替对象类型,但 JSON 不验证内部字段,并且不能保证它们在响应中,而不是一个选项。所以我遇到了同样的问题,但似乎这个解决方案不适用于:union = String | Int | MyTypeOne | MyTypeTwo ... MyTypeTen。有什么建议吗? @Mihail 除了使用 JSON 标量,您仍然可以创建一个自定义标量,其中包含特定于您的用例的验证。除此之外,如果您将其用于输出类型,您可以如上所述为父类型使用联合。

以上是关于graphql,联合标量类型?的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL.js - 时间戳标量类型?

GraphQL使用之graphql-java自定义标量类型

具有自定义标量类型的 GraphQL.js 突变

graphql-java:如何在以编程方式生成 graphql 模式时添加自定义标量类型?

使用graphql代码生成器时如何将自定义标量类型映射到打字稿类型?

Graphql-java 中的自定义标量