2. BFF层核心职责:数据聚合、接口适配、鉴权转发、降级熔断、前端专属逻辑编排
BFF(Backend For Frontend)层位于前端与后端微服务之间,其核心职责可归纳为五大能力域。理解这些职责是设计接口契约与测试策略的前提。
2.1 五大核心职责概览
| 职责 | 说明 | 契约测试关注点 |
|---|---|---|
| 数据聚合 | 将多个下游微服务的响应合并为一个前端友好的响应体 | 聚合字段的完整性、类型、空值处理 |
| 接口适配 | 转换后端接口的协议、数据格式、命名风格(如 REST → GraphQL) | 字段映射关系、枚举值转换、日期格式 |
| 鉴权转发 | 统一处理身份校验、Token 解析、权限校验后转发请求 | 鉴权失败时的错误码与响应结构 |
| 降级熔断 | 当依赖的下游服务不可用时,返回降级数据或触发熔断 | 降级响应的结构、熔断状态码、超时行为 |
| 前端专属逻辑编排 | 编排特定于当前前端的业务逻辑,如页面级数据组装、状态计算 | 编排结果的字段约束、条件分支覆盖 |
实践要点:BFF 的每一层职责都可能改变接口契约。契约测试必须覆盖“正常路径”与“职责触发路径”(如降级、鉴权失败),否则前端将面临不可预见的响应结构。
2.2 数据聚合与接口适配
数据聚合是 BFF 最直观的职责。前端一个页面请求,BFF 可能并发调用 3~5 个下游服务,然后合并结果。接口适配则负责消除前后端之间的格式差异。
// 示例:BFF 聚合用户信息与订单列表
// 下游响应
// GET /user-service/users/123 → { id: 123, name: "张三", email: "zhang@example.com" }
// GET /order-service/users/123/orders → [{ orderId: "O001", total: 99.9 }]
// BFF 聚合后响应给前端
{
"userId": 123,
"userName": "张三",
"email": "zhang@example.com",
"recentOrders": [
{ "orderId": "O001", "amount": 99.9 }
]
}
契约陷阱:聚合时若某个下游服务超时,BFF 可能返回部分数据或错误。契约测试必须明确约定“部分成功”场景下的响应结构,例如使用
errors 字段携带失败信息。
2.3 鉴权转发与降级熔断
鉴权转发是 BFF 的安全屏障。BFF 统一解析前端携带的 Token,校验身份与权限,再将用户身份信息(如 userId、角色)透传给下游。降级熔断则是 BFF 的容错机制,当依赖服务不可用时,BFF 应返回预设的降级数据而非直接报错。
// 鉴权转发流程(伪代码)
function handleRequest(req) {
const token = req.headers['authorization'];
const user = authService.verifyToken(token); // 鉴权
if (!user) {
return { status: 401, body: { code: "AUTH_FAILED", message: "无效令牌" } };
}
// 转发时携带用户身份
const orders = orderService.getOrders(user.userId, { headers: { 'x-user-id': user.userId } });
return { status: 200, body: orders };
}
降级策略示例:当订单服务超时,BFF 返回
{ "orders": [], "degraded": true, "message": "订单服务暂不可用" }。契约测试需验证降级响应中 degraded 字段为 true,且 orders 为数组。
2.4 前端专属逻辑编排
BFF 可以承载前端特有的业务编排,例如根据用户角色展示不同的页面模块、计算页面级状态、合并多个来源的数据并排序。这部分逻辑是 BFF 区别于通用 API Gateway 的关键。
// 前端专属编排示例:根据用户等级展示不同权益
function composeDashboard(user) {
const baseInfo = userService.getBaseInfo(user.id);
let privileges = [];
if (user.level === 'vip') {
privileges = ['免广告', '高清画质', '专属客服'];
} else {
privileges = ['基础功能'];
}
return { ...baseInfo, privileges, level: user.level };
}
2.5 核心职责与契约测试的映射关系
下图展示了 BFF 五大职责在请求处理链路中的位置,以及每个职责对应的契约测试切入点。
2.6 职责间的依赖关系
五大职责并非独立运行,它们之间存在明确的依赖与触发顺序。理解这些关系有助于设计更精准的契约测试用例。
- 鉴权转发 → 所有后续职责:鉴权失败时,后续的数据聚合、编排等职责不应执行。
- 数据聚合 → 接口适配:聚合后的数据通常需要经过适配转换才能返回给前端。
- 降级熔断 → 数据聚合:当某个下游服务降级时,聚合逻辑需要处理降级数据。
- 前端专属编排 → 最终响应:编排逻辑在聚合与适配之后执行,决定最终返回结构。
测试策略建议:为每个职责编写独立的契约测试,再编写跨职责的集成契约测试。例如,测试“鉴权失败 + 降级熔断”组合场景,确保 BFF 在鉴权失败时不会错误地触发降级逻辑。