在 GraphQL 中从模式拼接迁移到联邦时如何解决字段冲突?

问题描述

我正在尝试迁移依赖架构拼接的现有 GraphQL 代码,以改用联合。

我正在努力弄清楚如何优雅地处理与重复扩展/类型定义相关的错误。

我正在尝试遵循此存储库中的示例:https://github.com/apollographql/federation-migration-example

before-migration 文件夹中,项目定义了这样的架构:

  # user service
  type User {
    id: ID!
    firstName: String!
    lastName: String!
    address: String
  }
  # reservations service
  type Reservation {
    id: ID!
    userId: ID!
    reservationDate: String!
    status: String
  }
  # stitching gateway service
  extend type Reservation {
    user: User
  }

这个例子和我现在的配置很相似。

after-migration 文件夹中,他们有:

  # users service
  # This was originally in the stitched gateway
  extend type Reservation @key(fields: "id") {
    id: ID! @external
    userId: ID! @external
    user: User @requires(fields: "userId")
  }

有什么方法可以优雅地(没有停机时间)从一种模式迁移到另一种模式?当我尝试遵循这样的示例时,我从拼接服务中收到错误消息,提示 "Field "Reservation.user" already exists in the schema. It cannot also be defined in this type extension." 这是有道理的,因为我还没有从拼接服务中删除初始 extend type Reservation

问题是我相信基于这个例子,当从一种模式迁移到另一种模式时,必须会有一些停机时间。如果首先删除初始拼接类型扩展,则现有客户端尝试查询 Reservation.user 时会导致错误。如果在添加联邦风格的扩展之前没有删除初始扩展,那么这将引发冲突错误。

文档 https://www.apollographql.com/docs/federation/migrating-from-stitching/ 表明可以遵循特定步骤从拼接迁移到联合:

  1. 为您的子图添加联邦支持
  2. 在注册表中注册您的 GraphQL 架构
  3. 启动一个 Apollo Server 实例作为网关
  4. 将拼接逻辑从架构拼接网关迁移到子图
  5. 将流量从模式拼接网关移动到 Apollo Server 网关
  6. 从联合架构中移除架构拼接字段并完成迁移

我不明白如何以优雅的方式执行这些步骤。似乎第 4 步“将拼接逻辑从您的模式拼接网关迁移到您的子图”将不可避免地导致我上面提到的那种冲突。文档的编写方式似乎暗示这两种方法可以同时共存(文档甚至建议拼接服务器和联合服务器可以托管在同一进程中)。

我考虑过使用 transformSchemaonTypeConflict https://www.apollographql.com/docs/apollo-server/api/graphql-tools/#transformschema,但我很难理解这些可能如何适用于我的情况。文档说

mergeSchemas 的默认行为是取所有同名类型中第一个遇到的类型。

我相信这与我需要的不同,因为这是指类型而不是“根字段”。我想知道是否可以使用 FilterRootFields 以某种方式有条件地应用拼接类型扩展仅当该字段不存在时。不过,我不确定这到底是如何工作的,我找不到根据架构数据本身有条件地过滤根字段的示例。

是否有解决此问题的规范方法?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)