Summary
A BFF (Backend for Frontend) is a thin server that sits between one client — web, iOS, or Android — and the downstream services it needs. Instead of letting the client call five microservices and stitch the results together, the BFF makes those calls server-side, returns exactly the shape the UI needs, and handles auth token exchange in one place.
Jump to the interview angleBackend for Frontend (BFF)
A BFF is a dedicated backend owned by the frontend team, scoped to one client type. Sam Newman named the pattern: rather than one general-purpose API layer serving every consumer, you build one BFF per client so each can evolve its contract independently.
It solves two problems: over-fetching (REST endpoints built for one consumer force others to discard fields or make extra calls) and chatty clients (a mobile app paying three latency penalties for three round trips). The BFF fans those calls out in parallel server-side and returns one response. It also owns auth token exchange — holding refresh tokens or client secrets that must never reach the browser.
Route Handler fan-out (Next.js App Router)
A single app/api/dashboard/route.ts replaces three client round trips: read a HttpOnly cookie, exchange it for a service token, fan out with Promise.all, return one merged payload.
// app/api/dashboard/route.ts (Next.js 16, App Router)
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
const INTERNAL = process.env.INTERNAL_API_BASE!; // never reaches the browser
export async function GET() {
const session = (await cookies()).get("session")?.value;
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
// Exchange session cookie for a short-lived service token
const tokenRes = await fetch(`${INTERNAL}/auth/exchange`, {
method: "POST",
headers: { "x-session": session },
cache: "no-store",
});
const { token } = await tokenRes.json();
const headers = { Authorization: `Bearer ${token}` };
// Fan out to three services in parallel
const [user, orders, recs] = await Promise.all([
fetch(`${INTERNAL}/users/me`, { headers }).then((r) => r.json()),
fetch(`${INTERNAL}/orders?limit=5`, { headers }).then((r) => r.json()),
fetch(`${INTERNAL}/recs?context=dashboard`, { headers }).then((r) => r.json()),
]);
// Return exactly the shape the dashboard component needs
return NextResponse.json({ user, orders: orders.items, recs: recs.items });
}Reads a HttpOnly cookie, exchanges it for a service token, fans out to three services with Promise.all, returns one merged payload. INTERNAL_API_BASE stays in env.
BFF vs API Gateway
An API Gateway is shared infrastructure: it handles ingress, rate limiting, auth, and routing for all consumers. A BFF is a product-layer aggregator owned by one team. They coexist — the gateway sits at the edge; the BFF sits behind it, shaping data for one client type.
Tradeoffs
Pros
- Eliminates chatty client-to-service round trips by fanning out in parallel server-side.
- Each client team controls its own API contract without coordinating with other consumers.
- Auth secrets and service tokens stay on the server, never in browser memory.
- Downstream services can evolve independently; the BFF absorbs breaking changes.
- Reduces payload size — only the fields the UI actually renders are returned.
Cons
- Another service to deploy, monitor, and scale for each client type.
- Duplicates logic across BFFs if web and mobile need similar aggregations.
- Adds one network hop between client and services, slightly increasing p99 latency.
- Easy to turn into a fat, business-logic-laden service — scope creep is common.
Interview angle
Interviewers ask why you wouldn't just call microservices from the client. Hit: latency (parallel fan-out beats sequential client calls), security (secrets stay server-side), and client autonomy. Distinguish BFF from API Gateway — gateway is shared infrastructure; BFF is a product-layer aggregator owned by one team.
Soundbite: "The BFF is the API the UI wishes the backend exposed — shaped by the frontend team, not negotiated with everyone."
Key terms
- BFF
- Backend for Frontend — a server scoped to one client type that aggregates downstream APIs.
- fan-out
- Issuing multiple downstream requests in parallel, then merging results before responding.
- token exchange
- Swapping a session credential for a short-lived service token server-side, keeping secrets off the client.
- API Gateway
- Shared infrastructure proxy handling routing, rate limiting, and auth — not client-specific shaping.
- Route Handler
- Next.js App Router file (`route.ts`) that runs server-side and can act as a BFF endpoint.