Apollo Federation报错:字段标记@external但未在基础服务定义
错误根因
你遇到的组合报错是Apollo Federation的字段访问权限规则导致的:虽然Users服务已经定义了parentId字段,但默认情况下其他服务不能直接将其标记为@external引用,需要补充对应配置。
解决方案
根据你使用的Federation版本选择对应操作:
如果你使用Apollo Federation v2(当前主流版本)
v2默认所有字段仅归属定义它的服务独有,其他服务要引用该字段,必须在基础服务中将字段标记为@shareable:
- 先在Users服务的schema开头声明联邦指令导入:
extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key", "@shareable"])
- 修改Users服务的User类型定义,给
parentId加@shareable指令:
type User @key(fields: "id") { id: Int! @shareable name: String! surname: String! type: USER_TYPE! parentId: Int @shareable }
- 保持Payments服务的现有schema定义不变,重新启动服务即可完成schema组合。
如果你使用Apollo Federation v1
v1没有@shareable规则,报错一般是注册配置问题,请检查两个点:
- 确认Users服务的schema在网关注册时没有拼写错误,
parentId字段名、服务名Users MS和报错提示的完全匹配 - 确认Payments服务扩展User类型时的
@key(fields: "id")和Users服务的定义完全一致
验证配置
配置生效后,Payments服务的__resolveReference方法可以正常接收到网关传递的parentId参数,示例resolver逻辑如下:
// Payments服务User resolver示例 User: { __resolveReference(user, context) { // user对象已包含@requires声明的parentId字段 return context.dataSources.paymentService.getSubscription(user.parentId); } }
内容的提问来源于stack exchange,提问作者Marcin Warzybok
相关产品推荐
相关产品推荐

