加入我们,于10月8日至10日在纽约市,了解 GraphQL Federation 和 API 平台工程的最新技巧、趋势和新闻。加入2024年在纽约市的 GraphQL 峰会
文档
免费开始

将GraphQL单体迁移到Apollo联邦的步骤

从GraphQL单体迁移到联邦超图的步骤

联邦服务器

💡 提示

要获取完整、分步教程,请查看Voyage II: Federating the monolith

与任何单体服务一样,随着单体API grows larger and receives contributions from more developers,团队可能会在修改和维护其 API时遇到困难。

将单体拆分为较小的 GraphQL API可能适合您的团队。借助 ,您可以在不牺牲依赖于统一API的客户端应用程序的情况下拆分单体。每个子图都可以独立更新、部署和扩展,同时贡献到单个统一模式。

以下是我们推荐的将单体 GraphQL API转换为联邦GraphQL API的步骤。

规划和准备

1. 在现有API前面放置一个路由器

通过制作一个“一个”的“联邦 ”来开始这个过程。您现有的单体可以在不更改任何模式的情况下作为 运行。

  1. 如果您尚未将架构发布到 ,在您的Studio组织中创建一个新的图。选择“”作为您的图架构。

  2. 使用以下命令将单体架构发布到 GraphOS Studio 作为一个 subgraph(根据需要修改您的 --routing-url--schema 路径):

    rover subgraph publish --name monolith \
    --schema ./schema.graphql \
    --routing-url http://monolith.prod.svc.cluster.local/graphql \
    --convert # necessary if you're publishing to an existing variant
  3. 实例部署到您的环境中。

    在您的环境中自托管 GraphOS Router 限于 GraphOS 企业计划。其他计划类型使用 GraphOS 的托管云路由。了解更多信息,请查看 价格页面

  4. 设置 报头传播,以便单体可以从 接收任何必要的报头。

  5. 设置内部路由规则,使客户端请求转向 router 而不是您的单体。

  6. 启用使用情况指标报告到 GraphOS Studio

  7. subgraph 检查添加到您的单体的CI管道中。

到此为止,客户端请求将发送到您的新 router 而不是单体,但它提供相同的架构,因此客户端将无法察觉区别。

您不仅为联邦化架构做了准备,现在还拥有对 级别的图使用情况和破坏性更改检测的可见性。

2. 识别实体

接下来,查看您架构中的所有类型,并识别可能的 实体。实体是构成您数据模型基础的类型,并且必须包括可以唯一识别其实例的

考虑这个旅行预订网站的架构

例如,如下类型UserReservationFlightHotel是唯一可识别的,而ProfileCancellationPolicyAmenity基本上是与这些实体关联的属性组。

3. 对实体进行分组

在您识别了实体后,根据它们的逻辑域或关注点对它们进行分组。这些组通常对应于产品边界,但它们也可能对应于团队边界。这将确定您将最终拥有多少

账户域航班域酒店域
账户飞机
用户航空公司酒店
航班预订
预订房间
座位

4. 按迁移的容易程度对实体排序

在您决定如何将类型迁移到其他时,首先考虑以下几点:

计算与相关联的值类型的数量。您在迁移实体时需要将所有这些类型复制到新的子图。具有较少相关,枚举和非实体的实体将更容易迁移。

只要您能返回一个实体引用,就无需同时移动相关实体。例如,如果您有访问Hotel外键的权限,则可以移动Room类型。

酒店子图
type Room @key(fields: "number") {
number: ID!
floor: Int
hotel: Hotel
}
type Hotel @key(fields: "id", resolvable: false) {
id: ID! # comes from rooms.hotel_id in the database
}

可能更安全、更容易地移动整个Room类型,但只移动Hotel类型的“骨架”。查询计划器可以从中查询其余的Hotel字段,直到您移动该类型。

迁移过程中您的查询计划将变得多复杂?

如果你从移动与其他类型深度互联的类型开始,可能会为你的's查询计划引入不必要的复杂性。例如,考虑以下查询:

query MyFlights {
me {
reservations {
flights {
...FlightDetails
}
}
}
}

查询返回属于特定User的对象的Reservation列表,每个Reservation都包含一系列Flight。如果你开始移动Reservation类型到另一个subgraph,此查询将产生一个"A→B→A"的查询计划(依次获取UserReservation以及Flight,三个并行的subgraph获取):

monolith
subgraph
monolith

在这个阶段,一个更好的选择可能是移动Flight类型,这样查询计划将更加高效,在获取UserReservation之后再获取Flight

monolith
subgraph

当你将一个类型移动到另一个subgraph时,你还应该移动返回该类型的所有根级别字段(例如Query.flight(id:)。这样,该类型的对象可以随着单个subgraph操作返回。在最佳情况下,查询计划可以只需更少的子图操作就获取任何额外的数据:

subgraph
monolith

在迁移类型之间的过程中,某些查询计划不可避免地变得更加复杂。通过对你的实体进行排名并将影响最小的那些首先移动,你可以最小化这种增加。

实现

1. 将你的单体做为一个真正的subgraph

现在你有了一个迁移计划,你可以开始进行架构和代码变更。第一个变更是将Apollo Federation subgraph规范添加到单体中。涉及步骤取决于你与单体语言和框架一起使用的Apollo-Federation兼容库

需要添加的最重要功能是定义你的实体(通过添加@key指令)并添加它们的引用解析器

2.部署你的新subgraph

从空的subgraph开始,快速设置部署和持续集成管道。你可以使用这个存根subgraph规范,它不会影响面向客户的架构:

extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@shareable", "@inaccessible"])
type Query {
_todo: String @shareable @inaccessible
}

在您的新的subgraph部署之后,设置模式检查和发布,以便您可以快速捕获错误,并开始为做出贡献。

  1. 首先,在单体中标记所有您打算移动到subgraph中的值类型(枚举和非实体对象类型),标记为@shareable
  2. 将类型和字段复制到subgraph模式中,并从单体导入它们的
  3. 部署subgraph并直接调用它进行测试。使用_entities根字段以测试实体之间的连接。

当您对新的subgraph的行为和性能满意时,您可以开始将所有流量移动到它,并清理单体。

  1. 使用@override指令来标记subgraph中的字段,用@override(from: "monolith")标识,告诉查询规划器优先考虑新的subgraph而不是单体。
  2. 从单体模式中删除类型和字段。
  3. 从单体中删除不需要的解析器。
  4. subgraph中移除@override指令。
  5. 在适当的时候,从subgraph中的类型和字段移除@shareable

4. 根据需要将其他功能迁移出单体

在迁移的后期,您可以决定是否保留单体以处理位于您域中间的少数实体(例如User),或者将单体完全解散成新服务并使其退役。无论如何,您的全新联邦化的GraphQL API的未来扩展都处于良好的位置。

下一页
首页
评价文章评价在 GitHub 上编辑编辑论坛Discord

©2024Apollo Graph Inc.,即 Apollo GraphQL。

隐私政策

公司