3、BFF与API Gateway的区别:职责划分、粒度控制、聚合逻辑、安全性考量

在微服务架构中,API Gateway 和 BFF 经常被混淆。虽然两者都位于客户端与后端服务之间,但它们的关注点、控制粒度以及职责边界有本质区别。本节从四个核心维度进行对比分析,帮助你在架构选型时做出准确判断。

3.1 职责划分:全局路由 vs 前端适配

API Gateway 的核心职责是统一入口、路由转发、跨横切关注点(认证、限流、监控)。它面向所有客户端,提供通用能力。BFF 的核心职责是为特定前端(Web、iOS、Android)定制 API,解决“一个后端无法同时满足多端需求”的矛盾。

核心原则:API Gateway 是“基础设施层”的组件,BFF 是“业务适配层”的组件。Gateway 不感知业务逻辑,BFF 则深度理解前端交互场景。
API Gateway vs BFF 职责对比 客户端(Web / iOS / Android) API Gateway 统一入口 · 路由 · 限流 · 认证 · 监控 协议转换 · 请求/响应日志 BFF for Web 页面聚合 · 数据裁剪 Session 管理 BFF for Mobile 轻量响应 · 离线缓存 Token 刷新 微服务集群(用户 / 订单 / 商品 / 支付) 职责边界 Gateway 不感知业务 BFF 深度适配前端

3.2 粒度控制:粗粒度路由 vs 细粒度编排

API Gateway 的粒度通常停留在服务级路由(如 /user/** → user-service),它不关心单个接口返回哪些字段。BFF 的粒度可以深入到字段级裁剪和接口级编排,为每个前端场景定制最精简的响应。

维度 API Gateway BFF
路由粒度 服务级(/order/*) 场景级(/order/detail)
数据裁剪 不支持或仅支持全局字段过滤 按前端需求精确返回字段
接口编排 不支持(仅透传) 支持串行/并行调用多个下游
响应合并 不支持 支持多服务结果合并为一个响应
错误处理 统一错误码映射 按前端场景定制错误提示
实践建议:在 Go 中实现 BFF 粒度控制时,推荐使用 sync.WaitGroup 或 errgroup 并发调用多个下游服务,然后使用结构体按需组装响应。避免在 BFF 中引入复杂业务逻辑,保持“编排 + 裁剪”的轻量定位。

3.3 聚合逻辑:透传 vs 编排

API Gateway 的聚合能力非常有限,通常只做请求转发和响应透传。BFF 则承担了服务聚合的核心职责,将多个微服务的输出组合成一个前端可直接使用的响应。

以下是一个典型的 BFF 聚合场景:移动端首页需要同时展示用户信息、订单状态和商品推荐。BFF 会并行调用三个服务,合并结果后返回。

// Go BFF 聚合示例(使用 errgroup)
type HomePageResponse struct {
    User    UserDTO    `json:"user"`
    Orders  []OrderDTO `json:"orders"`
    Recommends []ProductDTO `json:"recommends"`
}

func (bff *HomeBFF) GetHomePage(ctx context.Context, uid string) (*HomePageResponse, error) {
    g, ctx := errgroup.WithContext(ctx)
    var user UserDTO
    var orders []OrderDTO
    var products []ProductDTO

    g.Go(func() error {
        var err error
        user, err = bff.userSvc.GetUser(ctx, uid)
        return err
    })
    g.Go(func() error {
        var err error
        orders, err = bff.orderSvc.GetRecentOrders(ctx, uid, 5)
        return err
    })
    g.Go(func() error {
        var err error
        products, err = bff.recommendSvc.GetRecommends(ctx, uid, 10)
        return err
    })

    if err := g.Wait(); err != nil {
        return nil, fmt.Errorf("home page aggregation failed: %w", err)
    }

    return &HomePageResponse{
        User:       user,
        Orders:     orders,
        Recommends: products,
    }, nil
}
注意:BFF 的聚合逻辑不应包含业务规则(如价格计算、状态机流转)。业务规则应下沉到领域服务中,BFF 只做“数据搬运”和“格式转换”。违反此原则会导致 BFF 变得臃肿,丧失其轻量适配层的优势。

3.4 安全性考量:边缘防护 vs 上下文安全

API Gateway 和 BFF 在安全层面承担不同角色,两者形成分层防御体系。

  • API Gateway 的安全职责:
    • 全局认证(OAuth2、JWT 校验)
    • IP 白名单 / 黑名单
    • 速率限制(Rate Limiting)
    • DDoS 防护
    • TLS 终止
  • BFF 的安全职责:
    • 用户上下文注入(从 Token 解析用户 ID、角色)
    • 数据级权限过滤(只返回当前用户有权限的数据)
    • 防数据过度暴露(只返回前端需要的字段,避免泄露敏感字段)
    • 前端特定安全策略(如 CSRF Token、Session 绑定)
分层安全防御模型 第一层:API Gateway(边缘防护) TLS · JWT 校验 · 限流 · IP 黑白名单 · DDoS 防护 第二层:BFF(上下文安全) 用户上下文注入 · 数据权限过滤 · 字段裁剪 第三层:微服务(领域安全) 领域权限校验 · 数据完整性 · 操作审计 安全分层原则 外层防攻击 内层防越权

3.5 综合对比总结

对比维度 API Gateway BFF 选型建议
职责定位 基础设施层统一入口 业务适配层前端定制 两者共存,不互斥
粒度控制 服务级路由 字段级 + 场景级 多端差异大时必选 BFF
聚合逻辑 不支持或极弱 强编排能力 移动端优先使用 BFF
安全性 边缘防护(防攻击) 上下文安全(防越权) 分层防御,缺一不可
团队归属 基础设施 / SRE 团队 前端 / 全栈团队 按组织架构划分
变更频率 低(稳定配置) 高(随前端迭代) BFF 独立部署,独立发布
架构黄金法则:API Gateway 做“通用”,BFF 做“定制”。在 Go 项目中,通常使用 kong、tyk 或 nginx 作为 API Gateway,使用独立的 Go HTTP 服务(基于 gin、echo 或 fiber)实现 BFF。两者通过内部 DNS 或服务发现进行通信,BFF 不对外暴露,仅由 Gateway 反向代理。