简介
现代应用程序由微服务驱动,这提高了可扩展性和灵活性,但也增加了客户端与服务器之间通信的复杂性。当一个前端需要从多个微服务中检索数据时,通常必须进行多次 API 调用,每次调用不同的后端。这会导致延迟增加、网络开销变大以及前端逻辑变得复杂。
API 聚合是一种架构模式,API 网关将来自多个后端服务的响应组合成一个单一的响应。这种方法减少了网络往返次数,简化了前端代码,并在网关层集中了相关逻辑。
本指南将带你了解在 API 网关中实现 API 聚合的所有相关知识——从概念基础到生产就绪的示例。
什么是 API 聚合?
API 聚合是指将来自多个后端 API 的响应组合成一个单一的响应。这是一种常见的架构模式,尤其是在由微服务构建的系统中。
示例场景
一个移动应用主页需要以下数据:
- 最新商品 (
/product/latest) - 用户资料 (
/user/me) - 购物车摘要 (
/cart/summary)
不使用聚合:
- 前端发起 3 次 HTTP 调用
- 必须处理重试和部分失败
- 需要编写逻辑来同步结果
使用聚合:
- 对
/api/homepage发起一次调用即可返回所有数据 - 逻辑集中在网关或聚合层
为什么 API 聚合在微服务架构中至关重要
在单体系统中,后端数据通常来自单一数据源。在微服务中,数据分布在多个服务中:
| 挑战 | 聚合的帮助 |
|---|---|
| 多次网络往返 | 合并为一次调用 |
| 网络延迟 | 显著降低 |
| 前端复杂性 | 简化逻辑 |
| 响应格式不一致 | 标准化统一 |
| 部分失败 | 集中的降级逻辑 |
何时使用 API 聚合
在以下情况下应使用 API 聚合:
- 前端在一次用户交互中频繁调用多个服务
- 多次调用带来的延迟成本过高
- 希望将聚合逻辑从客户端剥离
- 移动端或 Web 应用需要 BFF(Backend-for-Frontend,服务于前端的后端)层
但避免过度使用聚合,例如:
- 服务之间独立变更(可能导致强耦合)
- 可以通过缓存或 CDN 解决延迟问题的情况
- 需要在微服务级别进行细粒度访问控制的系统
常见的聚合模式
1. 扇出聚合(Fan-out Aggregation)
- 网关并行向多个服务发送请求,并将结果组合在一起。
2. 链式聚合(Chained Aggregation)
- 一个服务的响应结果被用作另一个服务的输入。
3. 条件聚合(Conditional Aggregation)
- 根据客户端请求或令牌(Token),调用不同的一组服务。
API 网关如何实现聚合
支持聚合的网关通常会:
- 接收单一客户端请求
- 将请求扇出(fan out)至多个后端(通常是异步的)
- 等待所有响应(带有超时/降级机制)
- 组合并返回聚合后的响应
支持聚合的技术:
- Apache APISIX:通过插件实现
- Kong:通过自定义插件或 Kong Gateway Enterprise
- NGINX:通过 Lua 或 NGINX Plus JavaScript
- Envoy:通过过滤器或借助 BFF 服务
API 网关中 API 聚合的架构
不使用网关的聚合
1sequenceDiagram
2 participant Client
3 participant Service A
4 participant Service B
5 participant Service C
6 Client->>Service A: GET /user
7 Client->>Service B: GET /orders
8 Client->>Service C: GET /recommendations使用网关的聚合
1sequenceDiagram
2 participant Client
3 participant API Gateway
4 participant Service A
5 participant Service B
6 participant Service C
7 Client->>API Gateway: GET /homepage
8 API Gateway->>Service A: GET /user
9 API Gateway->>Service B: GET /orders
10 API Gateway->>Service C: GET /recommendations
11 API Gateway-->>Client: 聚合响应GraphQL vs REST 聚合
虽然 GraphQL 经常被宣传为 API 组合的解决方案,但它也存在一些权衡。
| 特性 | REST 聚合 | GraphQL |
|---|---|---|
| 基于网关 | ✅ | ❌ (通常基于独立服务器) |
| Schema 灵活性 | 低 | 高 |
| 缓存简易度 | 高 | 中 |
| 工具生态 | 成熟 (REST) | 发展中 |
| 调试 | 较易 | 需要 introspection 工具 |
基于网关聚合的 REST 提供了精细的控制和网关级别的可见性,这非常契合云原生的可观测性实践。
API 聚合的实现方法
1. 网关层聚合(推荐)
- 聚合逻辑放置在 API 网关内部。
- 易于管理、具备可观测性且集中化。
2. 中间件 / BFF 方法
- 独立的服务充当聚合器。
- 逻辑更灵活,但引入了新组件。
3. 客户端聚合(微服务中的反模式)
- 客户端进行编排;用户体验差,延迟高。
总结
API 聚合是提升现代应用程序性能和用户体验的关键因素。通过将响应编排任务卸载给 API 网关或专用服务,团队可以降低前端复杂性并提高系统效率。
无论你使用网关原生插件还是后端编排器,目标都是为客户端提供快速、一致且可靠的 API。评估你的用例,选择合适的模式,并应用最佳实践以确保聚合逻辑的稳健和可维护性。
对于像 Apache APISIX 这样可扩展、可插拔且云原生的 API 网关来说,实现 API 聚合既灵活又强大。
常见问题解答 (FAQs)
1. API 聚合 (API aggregation) 和 API 组合 (API composition) 有什么区别?
这两个术语经常互换使用,但组合(composition)可能意味着更广泛的编排、转换和逻辑处理层。
2. 在前端聚合 API 可以吗?
对于简单的应用是可以的。但对于复杂的、对延迟敏感或有安全要求的应用,建议优先考虑服务端聚合。
3. 哪些 API 网关开箱即用地支持聚合?
Apache APISIX、Kong(通过插件)、Tyk 和 Gravitee 都通过插件或脚本支持聚合。
