GraphQL Federation 是一种将多个 GraphQL 服务组合成统一 API 的架构模式。它解决了微服务架构中的数据聚合问题。
核心概念
子图(Subgraph)
子图是独立的 GraphQL 服务,负责特定领域的业务逻辑。每个团队可以独立开发和部署自己的子图。
1# 用户子图
2type User @key(fields: "id") {
3 id: ID!
4 name: String!
5 email: String!
6}超图(Supergraph)
超图是将所有子图组合后形成的统一 GraphQL 模式,客户端可以像访问单一 API 一样查询所有数据。
网关(Gateway)
网关负责接收客户端查询,将其分解为子查询,并分发给相应的子图,最后合并结果返回给客户端。
Federation 架构
1客户端
2 ↓
3Gateway(Federation 网关)
4 ↓
5├─ 用户子图
6├─ 订单子图
7├─ 商品子图
8└─ 库存子图
关键特性
1. 实体(Entities)
实体是跨子图共享的类型,使用 @key 指令定义:
1type Order @key(fields: "id") {
2 id: ID!
3 user: User!
4}2. 扩展类型
一个子图可以扩展另一个子图定义的实体:
1# 订单子图扩展用户类型
2type User @key(fields: "id") {
3 id: ID! @external
4 orders: [Order!]!
5}3. 查询规划
网关自动分析查询,确定需要从哪些子图获取数据:
1query {
2 user(id: "1") {
3 name # 来自用户子图
4 orders { # 来自订单子图
5 total
6 }
7 }
8}优势
- 团队自治:每个团队独立拥有和开发子图
- 统一接口:客户端获得单一端点访问所有数据
- 类型安全:跨服务的类型系统保证数据一致性
- 渐进式采用:可以逐步将现有服务迁移到 Federation
与 API 网关的关系
Federation 网关与 API 网关可以协同工作:
- API 网关处理认证、速率限制等横切关注点
- Federation 网关专注于数据编排和查询路由
1客户端 -> API 网关 -> Federation 网关 -> 子图最佳实践
- 按业务领域划分子图
- 最小化子图之间的依赖
- 使用实体作为跨域边界
- 实现子图的健康检查
- 监控查询性能和错误率