(Apollo) GraphQL 合并模式

Posted

技术标签:

【中文标题】(Apollo) GraphQL 合并模式【英文标题】:(Apollo) GraphQL Merging schema 【发布时间】:2019-03-01 10:21:56 【问题描述】:

我正在使用 Apollo 提供的 GraphQL 工具/库。

是否可以将远程 GraphQL 架构合并到嵌套结构中?

假设我有n 远程模式,我想将来自不同模式的QueryMutationSubscription 合并到一个模式中,除了每个远程模式都放在自己的@987654325 下@。

假设我们有一个名为MenuX 的远程模式:

type Item 
  id: Int!
  description: String
  cost: Int


type Query 
  items: [Item]

还有一个名为 MenuY 的远程架构:

type Item 
  id: Int!
  name: String
  cost: Int


type Query 
  items: [Item]

我想将架构合并为一个架构,但在它们自己的类型下。一个人为的例子:

type MenuXItem 
  id: Int!
  description: String
  cost: Int


type MenuYItem 
  id: Int!
  name: String
  cost: Int


type MenuXQuery 
  items: [MenuXItem]


type MenuYQuery 
  items: [MenuYItem]


type Query 
  MenuX: MenuXItem
  MenuY: MenuYItem

我们可以看到,在Query 类型下,它包含两个新类型,其中包含来自远程模式的查询类型。来自架构MenuXItem 已通过使用来自graphql-tools 的转换器重命名,同样来自架构MenuYItem 也已被转换。

但是结构也可以转换吗?

对于实际的远程模式,我们正在查看每个模式的数百种类型,理想情况下,我不想污染 GraphiQL 中的根类型和自省文档。

【问题讨论】:

【参考方案1】:

Apollo 的 graphql-tools 包含一个transform schemas 的模块。您应该可以使用类似的东西重命名MenuX 中的所有内容

import 
  makeRemoteExecutableSchema,
  transformSchema,
  RenameTypes
 from 'graphql-tools';
const schema = makeRemoteExecutableSchema(...);
const menuXSchema = transformSchema(schema, [
  RenameTypes((name) => `MenuX$name`)
]);

然后你可以use the transformed schema作为mergeSchemas的输入。

请注意,*** QueryMutation 类型有些特殊,您可能希望尝试更直接地合并这些类型而不重命名它们,尤其是在它们不冲突的情况下。

【讨论】:

很遗憾,这并没有回答“可以将远程 GraphQL 模式合并到嵌套结构中吗?”的问题。转换对于根下的所有内容(查询、突变、订阅)都非常有用,但我也想将它们转换为嵌套结构。 (TFM 说“根对象永远不会被此转换重命名”,而您确实明确提出了这个要求。) 除非我遗漏了什么,否则重命名字段与将其嵌套在新部件项下是不同的。在我所见的任何地方,重命名字段以向 name 添加前缀就是示例,但不是在新父级下嵌套远程模式。这是可取的,以免污染根级。有什么想法吗?【参考方案2】:

有一个 Gatsby 插件,其中包含一个转换器,可以满足您的需求:https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/transforms.js

它对现有 GraphQL 模式的类型进行命名空间,因此您最终得到:

type Namespace1Item 
    ...


type Namespace2Item 
    ...


type Namespace1Query 
    items: [Namespace1Item]


type Namespace2Query 
    items: [Namespace2Item]


type Query 
    namespace1: Namespace1Query
    namespace2: Namespace2Query

所以,如果你转换你的模式并将它们合并,你应该很好。

【讨论】:

【参考方案3】:

可以实现Query 类型将根字段作为源模式的入口点的模式,但仅对于Query 类型作为Mutation 类型不支持名称下的突变嵌套。

因此,前缀名称是模式拼接的首选解决方案。

【讨论】:

以上是关于(Apollo) GraphQL 合并模式的主要内容,如果未能解决你的问题,请参考以下文章

身份验证Apollo Graphql for android

将 GraphQL 模式拆分为 express-graphql 中不同模块的最佳方法?

合并 Apollo 服务器的 GraphQL 解析器不使用 Object.assign()

Apollo GraphQL - 将 .graphql 模式导入为 typeDefs

在 apollo 模式之后出现“错误:GraphQL 模式文件应包含有效的 GraphQL 内省查询结果”:下载

GraphQL,Apollo 服务器联合模式