2. BFF 架构模式:职责、边界与部署
BFF(Backend For Frontend)并非凭空出现的模式,它是在微服务架构与前端多样化需求碰撞中演化出的中间层。理解 BFF 与微服务、API Gateway 的关系,以及它的典型部署方式和职责边界,是后续优化接口调用的基础。
2.1 BFF 与微服务的关系
BFF 是微服务架构的前端适配层,而非替代品。微服务提供通用的业务能力,BFF 则将这些能力按前端场景重新编排。
| 维度 | 微服务 | BFF |
|---|---|---|
| 关注点 | 业务领域能力(订单、用户、商品) | 前端体验聚合(首页、详情页、个人中心) |
| 粒度 | 细粒度,单一职责 | 粗粒度,按页面/场景聚合 |
| 数据格式 | 通用数据结构(如 Protobuf) | 前端友好格式(JSON,字段精简) |
| 调用方 | 其他微服务、BFF、API Gateway | 仅前端(Web、iOS、Android) |
| 部署频率 | 按业务迭代独立部署 | 随前端版本同步发布 |
实践建议:BFF 不应包含业务逻辑,只做数据聚合、裁剪、格式转换。业务规则应下沉到微服务层,避免 BFF 变成“胖中间层”。
2.2 BFF 与 API Gateway 的区别
很多团队将 BFF 与 API Gateway 混为一谈,实际上两者职责完全不同。API Gateway 是全局流量入口,BFF 是面向特定前端的业务聚合层。
| 对比项 | API Gateway | BFF |
|---|---|---|
| 核心职责 | 路由、限流、认证、日志、协议转换 | 数据聚合、字段裁剪、接口编排 |
| 数量 | 通常 1 个(或主备) | 按前端类型 N 个(Web BFF、App BFF) |
| 业务感知 | 无状态,不感知业务 | 强感知,按页面需求定制 |
| 变更影响 | 影响所有后端服务 | 仅影响对应前端 |
| 典型技术 | Kong、Nginx + Lua、Zuul | Node.js、Go、Java(轻量服务) |
常见误区:不要试图用 API Gateway 的聚合功能替代 BFF。Gateway 的聚合通常基于模板或简单脚本,难以应对复杂的前端编排逻辑,且会污染网关的稳定性。
2.3 BFF 的典型部署架构
下图展示了一个包含 API Gateway、BFF 层和微服务层的典型部署拓扑。前端请求先经过 Gateway 做安全校验和路由,再分发到对应的 BFF 实例,BFF 并行或串行调用多个微服务完成数据聚合。
2.4 BFF 的职责边界
明确 BFF 该做什么、不该做什么,是避免架构腐化的关键。以下清单可作为团队评审的检查项:
✅ BFF 的职责(应该做)
- 数据聚合:将多个微服务的响应合并为一个前端需要的 JSON 结构。
- 字段裁剪:移除前端不需要的字段,减少传输体积。
- 格式转换:将微服务的 Protobuf/Thrift 转为 JSON,或调整日期、枚举等格式。
- 降级与超时:当某个微服务超时或失败时,返回默认值或部分数据,保证页面可渲染。
- 会话适配:将前端的 Token/Cookie 转换为微服务所需的认证上下文。
❌ BFF 的职责(不应该做)
- 业务逻辑:不要写价格计算、库存校验、状态机等业务规则。
- 持久化:BFF 不应直接操作数据库或缓存(仅限透传)。
- 全局路由:不要替代 API Gateway 做服务发现、负载均衡。
- 复杂事务:不要跨多个微服务做分布式事务,应通过 Saga 或事件驱动下沉。
边界原则:BFF 的代码量应保持轻量。如果某个 BFF 的代码超过 2000 行,或者它开始包含 if-else 业务分支,说明职责已经越界,需要将业务逻辑抽回到微服务层。
2.5 多 BFF 的拆分策略
当团队维护多个前端时,需要决定如何拆分 BFF。常见的拆分维度有三种:
| 拆分维度 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 按前端类型 | Web / iOS / Android 差异大 | 隔离性强,互不影响 | 重复代码较多 |
| 按业务域 | 大型电商(首页 BFF、订单 BFF) | 职责单一,易于维护 | 前端需调用多个 BFF |
| 按版本 | 新旧版本共存期 | 平滑升级,灰度可控 | 运维成本增加 |
下图展示了按前端类型拆分的 BFF 内部调用模式,每个 BFF 独立编排微服务,互不干扰。
2.6 总结
BFF 是微服务与前端之间的“翻译官”和“调度员”。它不承担业务逻辑,只做聚合、裁剪和适配。与 API Gateway 的分工是:Gateway 管流量和安全,BFF 管数据和体验。在部署上,每个前端类型对应一个独立的 BFF 服务,按需调用微服务,实现前端聚合延迟的优化基础。