GraphQL Schema处理混合类型

Joe*_*Joe 6 graphql graphql-js

我最近开始研究使用GraphQL来请求动态数据配置的可能性.跳出来的第一件事是GraphQL的强类型概念.

GraphQL模式是否有办法处理混合类型对象的数组?我非常感谢您可以阅读的解释或可能的参考.

我目前正在使用GraphQL和Node.js,但稍后的实现将不在Java容器中.所有数据都将从MongoDB中获取JSON.

kaq*_*qao 6

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

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

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

自定义标量方法是唯一一种您不需要知道结果的可能类型的方法,即结果的结构可以是完全动态的。下面是该方法的一个实现,称为 JSON 标量(即将任何 JSON 可序列化结构填充到标量值中)。这种方法的一大缺点是它使得子选择变得不可能,因为整个值变成一个大标量(即使它是一个复杂的对象)。

由于问题是询问未知类型的对象数组,因此我会指出,您当然可以拥有上述所有选项的列表。

例子:

#Interface for any search result
interface SearchResult {
  title: String!
  url: String!
}

#A specific kind of search result
type Book implements SearchResult {
  title: String!
  url: String!
  author: Author!
  isbn: String!
}

type Article implements SearchResult {
  title: String!
  url: String!
  categories: [Category]!
}

type Query {
  #Search can return a mix of Books and Articles
  search(keyword: String!): [SearchResult!]
}
Run Code Online (Sandbox Code Playgroud)

或者

#No interface this time
type Book {
  name: String! #No common fields with Article
  author: Author!
  publisher: Publisher!
}

type Article {
  title: String!
  url: String!
  categories: [Category]!
}

union SearchResult = Book | Article

type Query {
  #Search can return a mix of Books and Articles
  search(keyword: String!): [SearchResult!]
}
Run Code Online (Sandbox Code Playgroud)

或者

scalar JSON

type Query {
  #Search can return anything at all... All bets are off
  search(keyword: String!): [JSON!]
}
Run Code Online (Sandbox Code Playgroud)

  • 因此,如果我阅读文档,并希望正确理解您的答案:似乎不可能使用混合结果的有序列表来实现类型化模式。示例:**混合搜索**。union 是“非此即彼”的返回类型,因此您不能使用它,因为您希望按相关性顺序返回混合结果。接口方法似乎没有问题,因为生成的类型是异构的。我是否认为 JSON 标量是唯一的选择?如果是这样的话,我宁愿回到 JSON-API... (2认同)

Ale*_*nko -1

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

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

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