2. BFF核心职责与定位
BFF(Backend For Frontend)是一种为特定前端界面(Web、iOS、Android、小程序等)提供专属后端的架构模式。它位于前端与通用后端服务之间,承担着请求聚合、数据裁剪、协议转换和前端适配四大核心职责。理解BFF与API Gateway的区别与联系,是掌握BFF架构设计的前提。
2.1 BFF四大核心职责
| 职责 | 说明 | 典型场景 |
|---|---|---|
| 请求聚合 | 将前端一次页面渲染所需的多个后端服务调用,合并为一次BFF请求 | 商品详情页需要调用商品、库存、价格、评价4个服务 |
| 数据裁剪 | 只返回前端实际需要的字段,去除冗余数据 | 移动端列表页只返回id、名称、缩略图,不返回描述、规格参数 |
| 协议转换 | 将后端异构协议(gRPC、Thrift、Dubbo)转换为前端友好的HTTP/JSON | 后端gRPC proto定义转为RESTful JSON接口 |
| 前端适配 | 根据前端设备、平台、版本差异,返回不同结构或格式的数据 | Web端返回完整HTML片段,App端返回精简JSON |
核心原则:BFF的存在是为了让前端不再关心后端服务的拆分细节,让后端服务不再为不同前端维护多套接口。每个前端团队拥有自己的BFF,实现“前端驱动后端”。
2.2 BFF请求聚合流程
下图展示了一个典型的BFF请求聚合过程:前端发起一次页面请求,BFF并行调用多个下游服务,合并结果后返回给前端。
实践建议:BFF内部应使用CompletableFuture或响应式编程(如WebFlux)实现并行调用,避免串行等待。聚合超时建议设置为下游服务P99延迟的1.5倍,防止单点故障拖垮整个聚合。
2.3 数据裁剪与协议转换
数据裁剪是BFF区别于通用API网关的关键能力。以下代码展示了一个典型的BFF数据裁剪实现:
// BFF层:只返回前端需要的字段
@GetMapping("/product/{id}")
public Mono<ProductVO> getProductDetail(@PathVariable Long id) {
return Mono.zip(
productService.getProduct(id),
inventoryService.getStock(id),
priceService.getPrice(id)
).map(tuple -> {
Product p = tuple.getT1();
Stock s = tuple.getT2();
Price pr = tuple.getT3();
// 数据裁剪:只返回前端需要的4个字段
ProductVO vo = new ProductVO();
vo.setId(p.getId());
vo.setName(p.getName());
vo.setStock(s.getAvailable());
vo.setPrice(pr.getCurrentPrice());
return vo;
});
}
注意:数据裁剪不是简单的字段过滤。BFF应主动剔除敏感字段(如内部ID、数据库时间戳)、大字段(如完整HTML描述)和前端不需要的关联数据。对于移动端,建议将裁剪后的响应体大小控制在10KB以内。
2.4 BFF与API Gateway的区别与联系
BFF和API Gateway是两种不同层次的架构组件,常被混淆。下表从多个维度进行对比:
| 对比维度 | API Gateway | BFF |
|---|---|---|
| 核心定位 | 统一入口、安全、路由、限流 | 为特定前端定制聚合与适配 |
| 部署粒度 | 全局通常1~2个实例 | 每个前端团队独立部署 |
| 业务逻辑 | 无业务逻辑,纯代理层 | 包含前端专属业务编排 |
| 数据裁剪 | 通常不做或仅做粗粒度过滤 | 精细化字段级裁剪 |
| 协议转换 | 支持HTTP/HTTPS、WebSocket | 可转换gRPC、Thrift、Dubbo等 |
| 版本管理 | 按API版本路由 | 按前端版本+平台适配 |
| 变更影响 | 变更影响所有调用方 | 变更仅影响对应前端 |
在实际架构中,BFF与API Gateway通常是分层协作的关系:
- 第一层:API Gateway — 负责全局横切关注点:认证鉴权、流量控制、请求日志、跨域处理、静态路由。
- 第二层:BFF — 负责前端专属业务逻辑:数据聚合、字段裁剪、协议转换、前端版本适配。
下图展示了BFF与API Gateway在整体架构中的分层协作关系:
架构决策要点:
- 如果团队只有1~2个前端,且后端服务数量较少,可先使用API Gateway+简单聚合层,暂不引入独立BFF。
- 当出现3个以上前端(如Web、iOS、Android、小程序、H5),且各端数据需求差异明显时,必须为每个前端独立部署BFF。
- BFF不应绕过API Gateway直接暴露给公网,安全策略统一在Gateway层实施。
2.5 典型BFF架构模式总结
综合以上分析,BFF在微服务架构中的定位可以归纳为以下模式:
- 每前端一BFF:每个前端团队维护自己的BFF服务,独立迭代、独立部署。
- BFF无状态:BFF不持有业务状态,所有状态下沉到后端服务或分布式缓存。
- BFF薄而专:BFF只做聚合、裁剪、转换、适配四件事,不包含复杂业务逻辑。
- BFF与Gateway分层:Gateway管安全与流量,BFF管前端适配,职责清晰。
演进路径:单体应用 → 单体+API Gateway → Gateway+简单聚合层 → Gateway+多BFF。不要在一开始就引入BFF,而是随着前端差异化需求的增长逐步演进。