与我们在10月8日至10日在纽约市举行的活动中相聚,了解关于 GraphQL Federation 和 API 平台工程的最新技巧、趋势和新闻。加入我们,在纽约市的 GraphQL Summit 2024 上
文档
免费开始

迁移到Apollo Federation 2

从Apollo Federation 1升级到Federation 2


📣 如果您还没有,查看Federation 2的新功能。

您可以将(而且应该!)您的 1 逐个组件迁移到Federation 2。您的supergraph在迁移过程中的每一步都将按预期工作,即使一些您的仍在使用Federation 1的模式。

迁移您的supergraph的每一步都有其自身的好处,因此完成尽可能多的步骤是有用的。您可以随时完成其余部分。

以下是迁移到Federation 2的三个步骤

Upgrade your
gateway
Use Federation 2
composition
Update individual
subgraphs

  1. 升级您的网关以支持Federation 2。

    您可以选择以下任意一个进行升级

    • GraphOS Router,一个高性能的预编译可执行文件(推荐)
    • 第2.x版本的@apollo/gateway库,以及第4.x版本的
  2. 使用Federation 2组合逻辑开始编写您的

  3. 更新您的单个子图以使用Federation 2功能和

正如所有基础设施更改一样,我们强烈建议在生产环境中执行之前,使用您的supergraph的测试实例完成每一步。

步骤 1: 升级您的网关

为了让您的 Federation 1 超级图支持 Federation 2,您首先需要将其网关升级到以下之一:

  • 。这是一个基于 Apollo Router Core 的高性能、预编译的可执行文件,并且与基于 Node.js 的网关相比提供了许多好处。
    • 我们建议您迁移到 GraphOS 路由器,除非您已经扩展了 Node.js 网关的功能,而这些功能目前 GraphOS 路由器不支持(这是不常见的)。
  • 库的 2.x 版本 @apollo/gateway,搭配 Apollo Server

注意

GraphOS 路由器和 @apollo/gateway v2.x 均支持 Federation 1。您可以直接升级而无需对 Federation 1 超级图进行任何其他更改,并且它将按预期工作。

迁移到 GraphOS 路由器

  • 要开始运行 GraphOS 路由器,请参阅 快速入门
  • 有关从 Node.js 网关迁移到 GraphOS 路由器的指导,请参阅 这篇文章

升级 @apollo/gateway 和 Apollo Server

的 @apollo/gateway@apollo/gateway库支持 Federation 2 超级图模式。从 2.0.0 版本开始,这些版本的 @apollo/gateway 需要 16.0.0 或更高版本的 graphql 库。

您可以使用以下命令在网关项目中安装这些库的更新版本

npm install @apollo/gateway graphql

Apollo Server 3.x 支持这些更新后的库版本,然而 Apollo Server 3.x 已被弃用。因此,我们强烈建议还将您的网关升级到 Apollo Server 4。

步骤 2:配置您的组合方式

联邦 2 使用一种全新的方法来组合 supergraph 模式表。这种方法与联邦 1 backward compatible,与联邦 1 subgraph 模式表子图兼容,并且即使对于联邦 1 的子图也提供了以下好处:

  • 帮助 组合提示当您的子图模式定义不一致时
  • 支持实现其他接口的接口(联邦 1 组合不支持)

按照以下说明配置您当前使用的任何组合方式:

在您配置这些更改后,请确保您的路由器正在使用您新创建的Federation 2supergraph模式。 (如果您使用托管联盟,则路由器将自动从Apollo获取新模式。)

您现在使用Federation 2组合来组合Federation 1子图。 最自然的问题接下来是,“这些子图的行为会发生什么变化?” 在下一步操作之前,答案是:没有任何变化!

注意

如果您的supergraph与Federation 2组合不成功,请查阅破坏性更改以了解最常见的原因。

步骤3:更新子图

注意

您可以逐个更新子图。 下面的步骤描述了如何修改单个子图以支持Federation 2,您可以在团队方便的时候为给定的子图执行这些步骤。

Federation 2提供了强大的新功能,需要您修改子图。 这些功能包括:

  • 在子图之间选择性共享类型和字段使用@shareable
  • 使用使用@override从一个子图安全地迁移字段到另一个子图
  • 使用使用@inaccessible隐藏内部路由字段,以便用户访问

您所做的模式更改与Federation 1不兼容,这意味着除非恢复这些更改,否则您将无法再使用Federation 1组合。

更新子图库

为了使用新的Federation 2功能和它们相关的指令,更新您的子图库到一个版本,该版本自动支持这些指令是非常有益的。

  • 如果您的子图使用Apollo Server和@apollo/subgraph库,则更新@apollo/subgraph到版本2.0.0或更高,例如:

    npm install @apollo/subgraph
  • 如果你的子图使用了另一个服务器库,请检查兼容性表以查看它是否支持Federation 2指令。如果支持,请查阅该库的文档,确定需要更新到哪个版本。

    • 如果你的库尚不支持Federation 2指令,如果你可以在你的模式中添加自定义指令定义,你仍然可以与Federation 2一起使用这个库!

选择Federation 2

向您的添加以下定义:

extend schema
@link(url: "https://specs.apollo.dev/federation/v2.0",
import: ["@key", "@shareable"])

此定义标识了一个模式为Federation 2模式,并且它导入了模式使用的任何Federation特定指令。没有这个@link定义,组合

注意

根据您的模式,您可能需要向导入数组中添加其他联邦指令,例如@external@provides

查看所有Federation特定指令。

如有必要,添加指令定义

目前,并非所有子图库都为Federation 2指令(如@shareable)提供内置支持。如果您的库不提供此支持,您需要将以下指令定义添加到您的子图模式中:

注意

一些子图库是“代码优先”的(它们从代码动态生成其模式),而不是“模式优先”(它们使用静态的模式文件)。对于代码优先库,手动添加这些指令定义并不直接。如果您在您的库中遇到这种情况,请通过提交问题

所有Federation 2指令的定义都可在本文中找到。我们与库维护者合作,帮助尽可能多的子图库自动添加这些模式定义。

标记所有值类型作为@shareable

在Federation 2中默认情况下,大多数架构字段仅通过单个子图可解析。在Federation 1中,对于值类型

Fed. 1(在Fed. 2中无效)

子图A
type Position {
x: Int!
y: Int!
}
子图B
type Position {
x: Int!
y: Int!
}

为了在Federation 2中使两个子图解析上述字段,两边的模式中都需要使用@shareable指令:

Fed. 2

子图A
type Position {
x: Int! @shareable
y: Int! @shareable
}
子图B
type Position {
x: Int! @shareable
y: Int! @shareable
}

注意

您也可以直接将对类型定义(如上面的Position)应用@shareable。这等价于对该类型所有字段的@shareable应用。

有关更多详细信息,请参阅值类型

更新实体定义

Federation 2对实体引入了微妙但强大的变化。这些变化需要相应更新您的子图模式中的定义。

移除不必要的语法

在Federation 1中,一个起源于一个子图,然后其他子图扩展实体以添加字段:

Fed. 1

产品(起源)
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
库存(扩展)
extend type Product @key(fields: "id") {
id: ID! @external
inStock: Boolean!
}

在Federation 2中,实体不再有一个起源子图。相反,每个子图都可以定义一个实体并为其贡献字段:

Fed. 2

产品
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
库存
type Product @key(fields: "id") {
id: ID!
inStock: Boolean!
}

注意上述Federation 2子图中的以下内容:

  • 库存子图不再扩展Product实体。
  • 库存子图不再将Product.id字段@external。
    • 外部@external 指令对于 @key 字段不再需要,但它对于 @requires@provides 仍然是必须的。
  • 即使没有标记为 @shareable,两个子图都可以解析 Product.id
    • 与大多数字段不同,如 Product.id 这样的 @key 字段默认是 @shareable。这对于 @key 字段是必要的,因为网关使用它们来将来自不同子图的数据关联到同一对象。

@provides 字段标记为 @shareable

与 Federation 1 一样,Federation 2 支持 @provides 指令,以便子图只解析特定查询路径的特定字段。

但是,如果子图为某个特定字段提供支持,则必须在始终可解析的每个子图中将该字段标记为 @shareable

Fed. 2

产品
type Product @key(fields: "id") {
id: ID!
name: String! @shareable
price: Int
}
库存
type Product @key(fields: "id") {
id: ID!
name: String! @external
inStock: Boolean!
}
type Query {
outOfStockProducts: [Product!]! @provides(fields: "name")
}

在这里,销售子图中的 Query.outOfStockProducts 提供了 Product.name 字段。因此,该字段必须在第 Products 子图(并在 Federation 1 的销售子图中,与 Federation 1 一样)中标记为 @shareable,否则将发生组成错误。

修改实体占位符的 @key

在某些情况下,子图引用了没有为它贡献任何字段的实体。在 Federation 1 中,这些情况看起来像以下这样:

Fed. 1

产品
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
评论
type Product @key(fields: "id") {
id: ID!
}
type Review {
product: Product!
score: Int!
}

上面的评论子图使用 Product 作为 Review.product 字段的返回类型,因此它需要为 Product 实体定义一个 "占位符"。这个占位符包含足够的信息来识别一个唯一的实例。

在 Federation 2 中,应像这样在占位符的 @key 参数中包含 resolvable: false,例如:

Fed. 2

产品
type Product @key(fields: "id") {
id: ID!
name: String!
price: Int
}
评论
type Product @key(fields: "id", resolvable: false) {
id: ID!
}
type Review {
product: Product!
score: Int!
}

设置 resolvable: false告知网关子图未为特定实体定义引用解析器。这最常见的是在 引用一个未为其贡献字段的实体 时。


已完成!你应该现在有一个成功地组装并充分利用了新联盟功能的Federation 2 超级图。如果你遇到问题,请通过社区论坛与我们联系。

上一页
Federation 1的变化
下一页
向后兼容
评分文章评分在GitHub上编辑编辑论坛Discord

©2024Apollo Graph Inc.公司,即Apollo GraphQL。

隐私政策

公司