我正在尝试迁移依赖模式拼接的现有 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/表明可以遵循特定步骤从拼接迁移到联合:
- 为您的子图添加联合支持
- 向注册表注册您的 GraphQL 模式
- 启动 Apollo Server 实例作为网关
- 将拼接逻辑从模式拼接网关迁移到子图
- 将流量从模式拼接网关转移到 Apollo Server 网关
- 从联合模式中删除模式拼接字段并完成迁移
我不明白如何以优雅的方式执行这些步骤。似乎第 4 步“将拼接逻辑从你的模式拼接网关迁移到你的子图”将不可避免地导致我上面提到的那种冲突。文档的编写方式似乎暗示两种方法可以同时共存(文档甚至建议拼接和联合服务器都可以托管在同一进程中)。
我考虑使用transformSchema
或onTypeConflict
https://www.apollographql.com/docs/apollo-server/api/graphql-tools/#transformschema但我很难理解这些可能如何适用于我的情况。文件说
的默认行为
mergeSchemas
是采用所有同名类型中第一个遇到的类型。
我相信这与我需要的不同,因为这指的是类型而不是“根字段”。我想知道是否可以仅在该字段不存在的FilterRootFields
情况下以某种方式有条件地应用拼接类型扩展。我不确定这到底是如何工作的,我找不到基于模式数据本身有条件地过滤根字段的示例。
有没有解决这个问题的规范方法?