| name | metaframe-api-composition-pattern |
|---|---|
| category | api |
| description | API 组合模式 | API & Integration |
英文名: API Composition Pattern
分类: API 设计与集成
作者: Chris Richardson
复杂度: intermediate
成熟度: established
AI 相关: ❌ 否
将多个微服务 API 聚合为统一接口,让客户端无需进行跨服务联结即可满足查询需求
- 扇出/扇入:组合器将单个客户端请求扇出为多个并行子请求发送至各微服务,再通过扇入将所有子响应合并为单个统一响应
- 部分失败容错:设计组合响应在子服务不可用时优雅降级——返回缓存值、null 或指示器值,而非将错误传播到整个响应
- 基于共享键的数据联结:使用共享领域标识符(order_id、customer_id)组合多个服务的数据,生成在单体架构中需要数据库联结的去规范化视图
- 超时预算:组合操作必须在考虑最慢子请求的挂钟超时内完成;为每个子请求实现超时可防止单个慢速服务阻塞整个组合
- 幂等子请求:子请求尽可能应为只读(GET 操作);如果组合过程中需要写操作,必须使用 Saga 模式安全协调分布式事务
- 识别需要来自多个微服务数据的客户端查询,该查询无法由单个服务高效满足,否则会引入服务间的紧密耦合
- 实现一个组合器服务(或 API 网关策略),接收客户端请求,向涉及的微服务并行发出子请求,并在定义的超时时间内等待所有响应
- 合并和转换响应:通过共享标识符联结数据、过滤字段以匹配客户端所需模式、应用业务规则(如聚合总计、推导计算字段),并生成统一响应
- 处理部分失败:为每个子请求定义回退策略(返回缓存数据、返回 null、在响应中返回错误指示器),使单个服务中断不会使整个组合响应失效
- 优化性能:并行化独立子请求,在允许新鲜度的地方缓存子响应,并通过 API 网关将组合端点暴露给外部,配置响应缓存和速率限制
['当客户端 UI 页面需要显示多个微服务拥有的数据时(如订单详情页需要联结订单、客户、库存和支付数据)', '当替代方案——让客户端发起多次串行 API 调用——因往返次数和网络开销导致不可接受的延迟时', '当移动端或 Web 客户端处理能力或带宽有限,受益于服务端聚合以减少载荷大小和请求数量时', '当实现后端对前端(BFF)层,为特定客户端类型(移动端、Web、合作伙伴)定制 API 表面时']
- 并行化所有独立子请求——串行组合会成倍增加延迟,违背聚合目的;使用 async/await 或 Promise.all 模式执行并发子请求
- 定义比组合超时更短的单个子请求超时,使慢速下游服务在导致整个组合超时之前被切断
- 独立于各微服务 API 对组合 API 进行版本管理——内部服务变更不应要求客户端更新其组合端点调用
- 对请求间不变的参考数据(产品目录、用户资料)缓存子响应,减少频繁组合查询对下游服务的负载
- 不要将 API 组合用于必须跨服务原子执行的写操作——使用带补偿事务的 Saga 模式进行分布式写操作协调
- 不要在单个组合请求中组合超过 5-7 个子服务——深度扇出会增加延迟方差、故障概率和调试复杂度
- 不要通过错误消息将组合器的内部服务拓扑暴露给客户端——返回客户端友好的错误码并单独记录内部子请求失败
- 不要在客户端实现组合逻辑——服务端组合保持网络拓扑的私密性、降低客户端复杂度,并允许组合策略在不影响客户端的情况下演进
Sources: SDFrame (Software Design) MetaFrame: 🔌 API & Integration / API 与集成