大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
API 组合
移动端一页「课程详情」可能需要 课程、作者、进度、评论 四个微服务的数据。API 组合(API Composition) 在 聚合层 并行调多个下游,拼成 一个响应 给客户端——避免浏览器 N 次往返。
学习目标
- 理解聚合器 vs 客户端编排的分工
- 识别并行调用与部分失败的降级策略
- 对照 gql-rest 与 BFF 边界
客户端编排的问题
App ──GET /courses/1──► course-svc
App ──GET /users/42────► user-svc (4 次 RTT + 4 套错误处理)
App ──GET /progress────► progress-svc
App ──GET /comments────► comment-svc
移动网络下延迟叠加;各服务 DTO 版本不一致时 App 负担重。
API 组合器拓扑
┌──────────────────┐
App ──GET /pages/course-detail──► │ Composition API │
│ (或 Gateway 内) │
└────────┬─────────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
course-svc user-svc progress-svc
│ │ │
└──────────────┴──────────────┘
并行 Feign / WebClient
│
合并 JSON 返回
实现常放在 独立聚合服务 或 sc-gateway 后的 BFF(下一课 ip-bff)。
Spring 侧直觉
public CourseDetailPage compose(String slug, Long userId) {
CompletableFuture<Course> course = async(() -> courseClient.get(slug));
CompletableFuture<User> author = async(() -> userClient.getByCourse(slug));
CompletableFuture<Progress> prog = async(() -> progressClient.get(userId, slug));
return merge(course.join(), author.join(), prog.join());
}
配合 sc-feign 与超时;单路失败走 ip-circuit fallback(缺进度则显示「未开始」)。
与 GraphQL 的关系
| 方式 | 谁选字段 | 谁调下游 |
|---|---|---|
| REST 组合 | 服务端固定 DTO | Composition 服务 |
| GraphQL | 客户端 Query | Resolver 调下游(gql-resolvers) |
GraphQL 可看作 通用组合层;REST 组合适合 页面级、缓存友好 的固定聚合。注意扇出过大、读投影时间差(ip-cqrs)与部分字段降级,避免整页 500。
练习
- 设计
/pages/home需调哪些服务、哪些可并行 - 某下游超时,列出 2 种降级字段策略
- 对比 GraphQL 单次 Query 与本模式的运维成本
小结
API 组合 = 服务端替客户端跑 N 个调用并拼结果。 下一课:BFF 模式。