Apollo GraphQL如何查询同Schema多数据子集服务并合并结果
实现方案
完全可以实现,不需要在业务代码里逐个调用两个服务,用Apollo的网关能力就能做到自动请求分发、结果合并,对上游调用方完全透明。
方案1:用Apollo Federation实现(官方推荐)
这是Apollo生态原生支持的多服务编排方案,适配步骤如下:
- 把两个存用户数据的服务改造成Federation子图
- 两个服务原有Schema、业务解析逻辑基本不用改,只需要给
User类型加@key指令,标记id为实体唯一主键:type User @key(fields: "id") { id: ID! name: String! } - 两个服务分别补充
__resolveReference解析器,逻辑和你现有的fetchUser解析逻辑完全一致:收到传入的用户id,返回本地存储的对应用户数据就行。
- 两个服务原有Schema、业务解析逻辑基本不用改,只需要给
- 部署Apollo Federation网关,配置路由规则
- 针对带id参数的
fetchUser(id: ID!)查询:配置按id区间路由,id在1-10000的请求转发给Service1,id在10001-20000的请求转发给Service2,结果直接透传即可。 - 针对无参数的
fetchUsers查询:网关收到请求后会并行向两个子图发起同查询,拿到两个服务返回的用户数组后自动拼接为完整的全量列表,再返回给调用方。
- 针对带id参数的
方案2:用Schema Stitching实现(无改造适配存量服务)
如果你不想改动两个现有服务的代码,不想加Federation相关的配置,可以直接在网关层做远程Schema拼接:
- 网关启动时分别拉取Service1、Service2的完整Schema,因为两个服务Schema完全一致,直接做合并扩展即可,不会有字段冲突。
- 给网关上的
fetchUsers字段自定义解析器:内部并发发起对两个服务fetchUsers接口的请求,拿到两个返回的用户数组后直接拼接成完整列表返回。 - 给网关上的
fetchUser字段自定义解析器:根据传入的id所属区间,把请求转发到对应的服务,拿到结果直接返回。
两种方案的请求都是网关层并行发起的,不会有串行请求的额外耗时,性能和你手动写代码调用两个服务再合并结果完全一致,但所有分发、合并逻辑都收敛在网关层,业务侧不需要写重复的调用、合并代码,调用方只需要像请求普通单GraphQL服务一样请求网关即可。
内容的提问来源于stack exchange,提问作者theUser
相关产品推荐
相关产品推荐

