Backends for Frontends (BFF)
debt(d8/e7/b7/t6)
Closest to 'silent in production until users hit it' (d8), since no automated tool flags missing BFF; only manual analysis with Postman/Lighthouse reveals over-fetching and client mismatch, slightly less than d9 because performance monitoring may surface symptoms.
Closest to 'cross-cutting refactor across the codebase' (e7), introducing a BFF requires standing up a new service tier, rerouting clients, and migrating aggregation logic — more than a single-component refactor but not a full architectural rewrite.
Closest to 'strong gravitational pull' (b7), because once BFFs exist, every client-facing feature must decide which BFF owns it, contracts must be versioned per client, and team ownership boundaries shape future work.
Closest to 'serious trap' (t6-7), the misconception that BFF causes duplication leads teams to push business logic into it, contradicting its orchestration-only role; common mistakes confirm this is a frequently-misunderstood pattern, slightly below t7 since the naming does suggest its purpose.
Also Known As
TL;DR
Explanation
Rather than one general-purpose API serving all clients, the BFF pattern creates a thin backend layer per frontend type. The mobile BFF returns compact responses optimised for bandwidth; the web BFF aggregates multiple services into one round trip; the partner BFF exposes only allowed data. Benefits: frontend teams own their BFF, optimise responses without affecting other clients, evolve client-specific contracts independently, and handle client-specific auth concerns. Common with microservices architectures where different clients need very different data shapes.
Diagram
flowchart TD
subgraph Clients
MOB[Mobile App]
WEB[Web Browser]
PART[Partner API]
end
subgraph BFFs
MOB_BFF[Mobile BFF<br/>compact responses]
WEB_BFF[Web BFF<br/>aggregated responses]
PART_BFF[Partner BFF<br/>restricted data]
end
subgraph Microservices
US[User Service]
OS[Order Service]
PS[Product Service]
end
MOB --> MOB_BFF
WEB --> WEB_BFF
PART --> PART_BFF
MOB_BFF & WEB_BFF & PART_BFF --> US & OS & PS
style MOB_BFF fill:#1f6feb,color:#fff
style WEB_BFF fill:#238636,color:#fff
style PART_BFF fill:#6e40c9,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Putting business logic in the BFF — BFF should only orchestrate and transform, not implement rules.
- One BFF for all clients — defeats the purpose; each client type should have its own.
- BFF team owned by the backend — frontend teams should own their BFF for true independence.
- Not versioning the BFF — BFF contracts must be versioned like any other API.
Code Examples
// One API trying to serve everyone:
GET /api/product/42
// Mobile needs: name, price, thumbnail (3 fields)
// Web needs: full details, reviews, related (20 fields)
// Partner needs: name, sku, stock only (3 different fields)
// Response: all 25 fields to everyone
// Mobile: 10kb response, uses 500 bytes — 95% wasted
// Separate BFFs per client:
// mobile-bff/product/42:
GET /mobile/products/42 → { name, price, thumbnail } // 200 bytes
// web-bff/product/42 — aggregates from 3 services:
GET /web/products/42 → { name, price, images, reviews, related } // Full
// partner-bff/product/42:
GET /partner/products/42 → { name, sku, stockLevel } // Partner contract