What is the Backend for Frontend (BFF) Pattern?
Learn the Backend for Frontend (BFF) pattern: dedicated backends per client, when to use it, and its trade-offs versus one shared API.
Expected Interview Answer
The Backend for Frontend (BFF) pattern gives each distinct client type — web, mobile, third-party partner — its own dedicated backend layer that shapes, aggregates, and trims data from downstream microservices specifically for that client, instead of forcing every client through one generic, one-size-fits-all API.
A single shared API tends to either over-fetch for lightweight clients like mobile apps (wasting bandwidth and battery) or under-fetch for data-rich clients like admin dashboards, and it accumulates client-specific conditional logic that makes it hard to evolve safely. A BFF solves this by placing a thin service per client experience between the client and the microservices layer; each BFF calls the shared services it needs (often via API composition), reshapes and filters the response to exactly what its client renders, and can own client-specific concerns like session handling or push-notification formatting. The trade-off is more services to deploy, version, and keep consistent, plus some duplicated aggregation logic across BFFs, so teams typically adopt it only once distinct clients have genuinely divergent data and performance needs, not by default for every project.
- Each client gets a payload shaped exactly for its rendering needs, cutting over-fetching and under-fetching
- Client teams can evolve their BFF independently without destabilizing a shared generic API
- Keeps client-specific logic (formatting, session handling) out of shared domain services
- Simplifies each client’s integration since it talks to one purpose-built backend
AI Mentor Explanation
The BFF pattern is like having a separate press liaison for television, radio, and print journalists instead of one spokesperson reading the same generic statement to everyone. The TV liaison prepares short soundbites with visuals in mind, the radio liaison prepares longer spoken quotes, and the print liaison prepares detailed stats-heavy notes, all pulled from the same team management but shaped differently. Each liaison only fetches and formats what their specific outlet actually needs. That per-audience shaping of the same underlying information is exactly what a BFF does for each client type.
Step-by-Step Explanation
Step 1
Identify distinct client experiences
Recognize that web, mobile, and partner clients have genuinely different data and performance needs.
Step 2
Build one BFF per client type
Each BFF is a thin service owned near the client team, dedicated to serving that one client.
Step 3
BFF calls shared services
Each BFF composes calls to the underlying domain microservices, often via API composition.
Step 4
Reshape for the client
The BFF trims, aggregates, and formats the response into exactly what its client needs to render.
What Interviewer Expects
- Explains the over-fetching/under-fetching problem with one shared generic API
- Describes a BFF as thin, client-owned, and dedicated to one experience
- Notes the trade-off: more services to run/version versus tailored payloads
- Knows BFF and API composition are complementary, not competing patterns
Common Mistakes
- Building a BFF per client by default even when clients have near-identical needs
- Letting a BFF grow business logic that belongs in the shared domain services
- Not accounting for duplicated aggregation logic across multiple BFFs
- Confusing a BFF with an API gateway (a gateway routes; a BFF also reshapes for one specific client)
Best Answer (HR Friendly)
“A Backend for Frontend, or BFF, is a small backend built specifically for one type of client, like the mobile app or the web app, so that client gets exactly the data it needs in the shape it needs, instead of everyone sharing one generic API that is either too heavy or missing details for some clients. We only add a BFF once a client’s needs are different enough to justify a dedicated layer.”
Code Example
// mobile-bff.js — minimal payload for a small screen
async function getOrderForMobile(orderId) {
const order = await orderService.get(orderId)
return {
id: order.id,
status: order.status,
itemCount: order.items.length,
total: order.total,
}
}
// admin-bff.js — rich payload for an internal dashboard
async function getOrderForAdmin(orderId) {
const [order, customer, payments] = await Promise.all([
orderService.get(orderId),
customerService.get(orderId),
paymentService.getHistory(orderId),
])
return { order, customer, payments } // full detail, no trimming
}Follow-up Questions
- How is a BFF different from an API gateway that just routes requests?
- How do you avoid duplicating aggregation logic across several BFFs?
- When is it not worth introducing a BFF for a new client type?
- How would you version a BFF independently from the shared domain services it calls?
MCQ Practice
1. What problem does the BFF pattern primarily solve?
A BFF shapes data specifically for one client’s needs, avoiding the over-fetch/under-fetch problems of one shared generic API.
2. What is a common trade-off of adopting the BFF pattern?
Each BFF is an extra service to maintain, and similar aggregation logic can end up duplicated across multiple BFFs.
3. How does a BFF typically get the data it reshapes for its client?
A BFF is thin: it composes calls to shared services and reshapes the combined result for its specific client.
Flash Cards
What is the BFF pattern? — A dedicated backend per client type that shapes data from shared services for that client’s specific needs.
What problem does it solve? — Over-fetching or under-fetching caused by forcing all clients through one generic shared API.
Main trade-off of BFFs? — More services to run and version, and possible duplicated aggregation logic across BFFs.
BFF vs API gateway? — A gateway routes and enforces cross-cutting policy; a BFF also reshapes data specifically for one client.