Skip to content
fearchitect
Architecture & Composition

Backend for Frontend (BFF)

A per-client server layer that shapes and aggregates APIs for one frontend.

By Abas TurabliReviewed

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 angle

Backend 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.

Each client has its own BFF that fans out to shared downstream services, returning a client-shaped payload.

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.

Next.js 16 Route Handler as a BFFts
// 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.

Further reading

Search fearchitect

Jump to a topic, mode, or action.