(Apollo) GraphQL 合并模式
Posted
技术标签:
【中文标题】(Apollo) GraphQL 合并模式【英文标题】:(Apollo) GraphQL Merging schema 【发布时间】:2019-03-01 10:21:56 【问题描述】:我正在使用 Apollo 提供的 GraphQL 工具/库。
是否可以将远程 GraphQL 架构合并到嵌套结构中?
假设我有n
远程模式,我想将来自不同模式的Query
、Mutation
和Subscription
合并到一个模式中,除了每个远程模式都放在自己的@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
类型下,它包含两个新类型,其中包含来自远程模式的查询类型。来自架构MenuX
的Item
已通过使用来自graphql-tools
的转换器重命名,同样来自架构MenuY
的Item
也已被转换。
但是结构也可以转换吗?
对于实际的远程模式,我们正在查看每个模式的数百种类型,理想情况下,我不想污染 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
的输入。
请注意,*** Query
和 Mutation
类型有些特殊,您可能希望尝试更直接地合并这些类型而不重命名它们,尤其是在它们不冲突的情况下。
【讨论】:
很遗憾,这并没有回答“可以将远程 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