处理混合类型的 GraphQL Schema

Posted

技术标签:

【中文标题】处理混合类型的 GraphQL Schema【英文标题】:GraphQL Schema to handle mixed types 【发布时间】:2016-03-17 22:08:54 【问题描述】:

我最近开始研究使用 GraphQL 请求动态数据配置的可能性。让我印象深刻的第一件事就是 GraphQL 的强类型概念。

GraphQL 模式有没有办法处理混合类型对象的数组?我将不胜感激解释或可能是我可以阅读的参考。

我目前正在使用带有 Node.js 的 GraphQL,但以后的实现将在 Java 容器之外。所有数据将从 MongoDB 中提取为 JSON。

【问题讨论】:

GraphQL 为此提供了接口和联合。我认为我没有资格写出正确的答案,但您可以在文档中找到它:facebook.github.io/graphql/#sec-Interfacesfacebook.github.io/graphql/#sec-Unions 【参考方案1】:

您必须让这些不同的类型实现相同的接口,让您的解析器返回联合,或者创建一个自定义标量来保存动态数据。

最简洁的方法是第一种:如果生成的对象可以是有限数量的类型,请定义类型以使它们实现相同的接口,并通过接口键入解析器。这允许客户端根据实际类型有条件地选择子字段,并保持类型安全。

第二种方法也有类似的限制:您需要提前知道可能的类型,但它们不必实现相同的接口。当可能的值彼此不相关并且具有 either/or 语义(如成功/失败)时,这是更可取的。

自定义标量方法是唯一一种您不需要知道结果的可能类型的方法,即结果的结构可以是完全动态的。 Here's an implementation 这种方法,称为 JSON 标量(即将任何 JSON 可序列化结构塞入标量值)。这种方法的一大缺点是它使子选择成为不可能,因为整个值变成了一个大标量(即使它是一个复杂的对象)。

【讨论】:

因此,如果我阅读了文档,并希望能正确理解您的答案:似乎不可能使用混合结果的有序列表来实现类型化模式。示例:混合搜索。 union 是一种“非此即彼”的返回类型,因此您不能使用它,因为您希望按相关性顺序返回混合结果。接口方法似乎没有问题,因为结果类型是异构的。我是否正确地认为 JSON 标量是唯一的选择?如果是这样的话,宁愿回到 JSON-API... @Overbryd 这与 GraphQL 几乎没有任何关系。在任何类型化的语言中,您都不能只拥有一个混合内容列表,而这些内容要么具有一致的接口,要么通过拥有最通用类型的列表而失去类型安全性,例如List<Object> 在 Java 中。如果他们不知道结果会是什么形状,您的客户甚至会如何使用它?您实际上不太可能遇到这种情况。如果你真的这样做了,GraphQL 将无济于事。但是搜索结果都至少有一个标题和一个 URL 作为公共字段,不是吗? 这可能只是文档的编写方式。我现在进一步挖掘,使用联合类型,我可以解决我的问题。虽然,仅仅通过阅读文档,我不会猜到,联合类型是要走的路。【参考方案2】:

如果数据完全是 JSON,并且您希望按原样保留它们,请查看 JSON scalar type。基本上,

import  GraphQLObjectType  from 'graphql';
import GraphQLJSON from 'graphql-type-json';

export default new GraphQLObjectType(
  name: 'MyType',
  fields: 
    myField:  type: GraphQLJSON ,
  ,
);

【讨论】:

如何将过滤器与混合数据类型集成?【参考方案3】:

我认为可以制作适合需要的自定义/通用类型。 因此,它仍然是一个强类型数组,但类型足够灵活,可以设置您需要的内容。

这是一个自定义类型的示例: https://github.com/stylesuxx/graphql-custom-types

【讨论】:

这不是他想要的。他在问您是否可以进行查询以在同一个 json 数组中返回多种类型。假设您想显示一个日程安排,包括“事件”和朋友的生日,您想将它们作为单独的对象处理,因为它们具有不同的数据,并且应该以不同的方式显示,但按日期排序。

以上是关于处理混合类型的 GraphQL Schema的主要内容,如果未能解决你的问题,请参考以下文章

Nestjs(graphql)中不同类型的异常处理

你如何在 GraphQL 中处理多个类型的数组(例如:不同的内容块)?

离开页面时,我得到:未处理的 GraphQL 订阅错误错误:GraphQL 错误:未提供所需类型 xxx 的变量 xx

嵌入 Jetty 10 的 GraphQL 订阅

无法使用 graphql-middleware-sentry 从 GraphQL 接收错误

如何在 GraphQL (Relay) 中查询和改变数组类型?