使用GraphQL联邦遇SATISFIABILITY_ERROR问题求助
GraphQL Federation 子图检查报错解决方案
问题场景
在构建GraphQL Federation Supergraph时,两个子服务出现如下问题:
- 第一个子图(users)Schema:
type User @key(fields: id) @guard { id: ID! firstname: String! }
- 第二个子图Schema:
type GraphUnion { id: ID! user_id: Int text: String user: User! @hasOne } type User @extends @key(fields: "id") { id: ID! @external }
第二个子图中创建了User扩展类(路径app/graphql/types):
final class User { public function __invoke($representation): array { return [ '__typename' => 'User', 'id' => 23 ]; } }
执行rover subgraph check时触发错误:
SATISFIABILITY_ERROR: The following supergraph API query: { graphUnion { user { firstname } } } cannot be satisfied by the subgraphs because: - from subgraph "...": - cannot find field "User.firstname". - cannot move to subgraph "users", which has field "User.firstname", because type "User" has no @key defined in subgraph "users".
修复步骤
1. 修正第一个子图的@key语法
Apollo Federation要求@key指令的fields参数必须是字符串字面量,原写法@key(fields: id)不符合规范,会导致rover无法识别该子图的User类型定义了@key。修正后的Schema:
type User @key(fields: "id") @guard { id: ID! firstname: String! }
2. 修正第二个子图的User扩展解析逻辑
扩展类不能硬编码返回固定ID,需要使用传入的$representation参数中的ID(该参数由Gateway传递,包含从GraphUnion关联过来的用户标识),这样Gateway才能正确路由到users子图拉取firstname字段。修正后的代码:
final class User { public function __invoke($representation): array { return [ '__typename' => 'User', 'id' => $representation['id'] // 使用传入的关联ID,而非硬编码值 ]; } }
3. 验证子图注册名称一致性
确保执行rover subgraph check时指定的users子图名称,与Gateway中注册的子图名称完全匹配。报错中提到的subgraph "users"必须和第一个子图的实际注册名称一致,否则Gateway无法定位到对应子图。
4. 重新校验子图
修正完成后,重新发布子图,再次执行rover subgraph check验证问题是否解决。
内容的提问来源于stack exchange,提问作者Bogdan Lepinzan
相关产品推荐
相关产品推荐

