【问题标题】:(Apollo) GraphQL Merging schema(Apollo) GraphQL 合并模式
【发布时间】: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 中的根类型和自省文档。

【问题讨论】:

    标签: node.js graphql apollo-server


    【解决方案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 类型不支持名称下的突变嵌套。

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

      【讨论】:

        猜你喜欢
        • 2020-12-21
        • 2020-11-17
        • 2019-04-22
        • 2018-04-23
        • 2019-01-18
        • 2021-10-30
        • 2019-05-10
        • 2018-06-23
        • 2019-12-28
        相关资源
        最近更新 更多