0

我正在尝试迁移依赖模式拼接的现有 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情况下以某种方式有条件地应用拼接类型扩展。我不确定这到底是如何工作的,我找不到基于模式数据本身有条件地过滤根字段的示例。

有没有解决这个问题的规范方法?

4

0 回答 0