← 返回首页
🔗

BFF模式

📂 architecture ⏱ 1 min 162 words

BFF模式

BFF模式概述

Backend for Frontend(BFF)是一种架构模式,为每种前端应用创建一个专门的后端服务。BFF位于前端和微服务之间,负责聚合多个微服务的数据、适配不同前端的接口需求、处理前端特有的业务逻辑。BFF模式解决了微服务架构下前端直接调用多个后端服务的复杂性问题。

BFF的核心价值在于:让前端团队掌控自己的API层、为不同前端(Web、移动端、小程序)提供定制化的数据格式、减少前端的网络请求次数、在BFF层处理跨服务的数据聚合和转换。

from fastapi import FastAPI
from typing import Optional

app = FastAPI()

class WebBFF:
    """Web端BFF - 返回完整数据"""
    async def get_product_detail(self, product_id: str) -> dict:
        product = await product_service.get(product_id)
        reviews = await review_service.get_by_product(product_id)
        inventory = await inventory_service.get(product_id)
        
        return {
            "id": product.id,
            "name": product.name,
            "description": product.description,
            "price": product.price,
            "images": product.images,
            "reviews": {
                "average_rating": reviews.average,
                "count": reviews.count,
                "items": reviews.items[:5]  # Web端只显示5条
            },
            "in_stock": inventory.quantity > 0
        }

class MobileBFF:
    """移动端BFF - 精简数据"""
    async def get_product_detail(self, product_id: str) -> dict:
        product = await product_service.get(product_id)
        inventory = await inventory_service.get(product_id)
        
        return {
            "id": product.id,
            "name": product.name,
            "price": product.price,
            "thumbnail": product.images[0] if product.images else None,
            "in_stock": inventory.quantity > 0
        }

BFF的职责

BFF的主要职责包括:数据聚合(从多个微服务获取数据并组合)、接口适配(为不同前端提供定制的API契约)、协议转换(如将内部gRPC转换为前端友好的REST)、认证授权(处理前端的认证流程)、限流降级(保护后端服务)。

BFF不应该包含核心业务逻辑,其逻辑应该主要是数据处理和转换。如果BFF中出现了复杂的业务规则,应该考虑将这些规则下沉到微服务中。BFF应该保持轻量,避免成为新的单体。

BFF的组织方式

BFF的组织方式通常有两种:按平台划分(Web BFF、Mobile BFF、小程序BFF)和按业务线划分(订单BFF、商品BFF、用户BFF)。按平台划分适合不同前端需求差异大的场景;按业务线划分适合前端需求相对统一的场景。

选择组织方式时需要考虑:前端团队的结构、前端需求的差异程度、BFF的维护成本、服务的复用性。无论哪种方式,都应该避免BFF数量过多导致的维护负担。

# BFF路由示例
@app.get("/api/web/products/{product_id}")
async def web_get_product(product_id: str):
    """Web端产品详情"""
    bff = WebBFF()
    return await bff.get_product_detail(product_id)

@app.get("/api/mobile/products/{product_id}")
async def mobile_get_product(product_id: str):
    """移动端产品详情"""
    bff = MobileBFF()
    return await bff.get_product_detail(product_id)

@app.get("/api/web/orders")
async def web_list_orders(customer_id: str):
    """Web端订单列表 - 包含丰富信息"""
    orders = await order_service.list_by_customer(customer_id)
    enriched = []
    for order in orders:
        product_details = await product_service.batch_get(order.product_ids)
        enriched.append({**order.dict(), "products": product_details})
    return enriched