API 网关和 BFF 有什么区别?
简化版
API 网关承担跨客户端通用的入口能力,如路由、认证、限流和审计;BFF 面向某一类前端组织接口、聚合数据并适配体验。两者可以共存,但通用治理不应复制到每个 BFF,领域规则也不应塞进网关。
详细版
典型链路是 Client→Gateway→BFF→Domain Service。网关由平台团队治理稳定横切能力,Web、App 等 BFF 由对应体验团队维护端特有编排。BFF 可做字段裁剪和并行聚合,但关键写入仍由领域服务校验。
设计时限制调用扇出、总 deadline 和响应大小,明确部分失败展示;网关与 BFF 都要无状态扩容,传播身份、trace context 和取消信号。若所有客户端需求相同,一个网关加粗粒度 API 已足够,无需强行增加 BFF。
完整版教学
一、职责为什么要分开
网关面对所有入口,策略必须稳定一致;BFF 面对具体 UI,变化频率与页面迭代一致。把页面拼装放进全局网关,会让一次 App 改版影响所有客户端的入口发布。
记忆钩子:网关管“谁能进、往哪走”,BFF 管“这个端怎样拿得顺手”。
二、能力对比
| 维度 | API 网关 | BFF |
|---|---|---|
| 服务对象 | 所有客户端 | 单一端/体验 |
| 核心能力 | 路由、认证、限流 | 聚合、裁剪、编排 |
| owner | 平台团队 | 体验团队 |
| 变化频率 | 较低 | 跟随 UI 较高 |
| 业务规则 | 避免 | 仅展示编排 |
三、一次请求怎样流转
Mobile -> Gateway(auth/rate limit) -> Mobile BFF
|-> Product
|-> Inventory
+-> Promotion
BFF 可并行读取三个服务并构造页面模型;库存扣减仍调用库存服务,不能在 BFF 拼 SQL 或复制不变量。
四、聚合的延迟与失败
三个并行依赖耗时 80、120、300ms,全部必需时响应至少接近 300ms;若促销可选,可在 150ms 后降级为空。必须定义哪些分支必需、哪些可降级,而非遇错统一返回 500。
BFF 传播入口 deadline,取消已无意义的下游请求,并限制每次聚合的 fan-out,防止一个页面请求变成几十次 RPC。
五、安全边界
网关验证外部凭证并生成受信内部身份,BFF 做资源级授权上下文传递,领域服务仍执行最终业务授权。不能因为流量经过网关,就让内部服务完全信任用户传来的 header。
敏感字段在源服务和 BFF 都应最小化,日志不可记录完整 token 或聚合后的个人数据。
六、部署与治理
二者通常保持无状态,配置版本化并灰度。监控网关拒绝率、路由错误和全局延迟,同时监控 BFF 的依赖扇出、部分失败、响应体大小和端到端体验指标。
一个 BFF 若同时服务多个差异巨大的端,最终会充满条件分支;此时按体验拆分比继续扩展全局网关更清晰。
容量规划要分别计算两层:网关按全站入口峰值和认证成本扩容,BFF 按对应端的流量、聚合扇出与下游连接数扩容。
网关或 BFF 下线实例时应先停止接流,再等待在途请求完成,避免滚动发布把聚合请求截断。
七、常见误区与追问
- 误区:BFF 是另一层 API 网关。 它的核心是端特有体验适配。
- 误区:鉴权在网关做过,后端无需授权。 领域服务仍需资源级校验。
- 误区:所有聚合都应放 BFF。 跨端稳定的领域用例应由领域服务提供。
- 误区:增加一层必然改善性能。 聚合不当会增加跳数和扇出。
- 追问:BFF 能缓存吗? 可缓存端视图,但要定义身份、失效和新鲜度。
- 追问:GraphQL 是否等于 BFF? 它是接口技术,不能替代 owner 与边界设计。
- 追问:何时不需要 BFF? 各端需求一致且现有 API 已匹配体验时。
八、加强记忆
按“通用入口治理归网关、端特有编排归 BFF、业务不变量归领域服务”划界。链路上统一传播身份、deadline 和 Trace;BFF 的价值由减少端请求和改善体验证明,同时用扇出、降级和授权边界防止它变成新的业务单体。