Prompt

How do I build a Backend for Frontend?

Technology · Developer Tools / Developer tools2 observationsLast seen Jul 15, 2026

Latest observation

Jul 15, 2026 · OpenAI APIWeb search: off

A Backend for Frontend (BFF) is a backend service tailored to a specific frontend app or channel—like a web app, mobile app, or desktop client. Its job is to simplify the frontend by aggregating data, hiding internal service complexity, and shaping APIs around the UI’s needs.

Why build a BFF?

A BFF is useful when:

  • Your frontend needs data from multiple backend services
  • Different clients need different payloads or workflows
  • You want to reduce frontend complexity
  • You need to hide internal APIs or enforce UI-specific auth/authorization
  • You want to improve performance via aggregation, caching, or orchestration

Core responsibilities of a BFF

A BFF typically does:

  1. API composition: combine data from many services into one response
  2. Request orchestration: call services in sequence or parallel
  3. Payload shaping: return only what the client needs
  4. Auth/session handling: manage tokens, cookies, and user context
  5. Caching: reduce repeated downstream calls
  6. Error normalization: provide consistent error responses
  7. Rate limiting and resilience: protect downstream services

Typical architecture

Frontend (Web/Mobile)
        |
        v
      BFF
   /   |   \
  v    v    v
User  Order  Catalog Services
Service Service Service

The frontend talks only to the BFF. The BFF talks to internal services.


How to build one

1. Define the frontend’s use cases

Start from UI screens and actions, not backend entities.

Ask:

  • What pages/screens exist?
  • What data does each screen need?
  • Which operations are user-driven?
  • What latency is acceptable?

Example:

  • “Dashboard page needs user profile + recent orders + notifications”
  • “Checkout page needs cart + shipping options + payment intent”

This helps you design BFF endpoints around UI needs, not generic CRUD.


2. Design endpoint contracts for the frontend

Create endpoints that match frontend workflows:

Example:

GET /dashboard
GET /checkout/summary
POST /checkout/submit

Instead of exposing many granular backend calls to the client, the BFF can aggregate them.

Example response:

{
  "user": { "name": "Ava" },
  "orders": [...],
  "notifications": [...]
}

3. Implement orchestration and aggregation

Use the BFF to call downstream services and merge results.

Pseudo-flow:

  • Call User Service
  • Call Orders Service
  • Call Notifications Service
  • Combine results into one response

Use parallel calls where possible to reduce latency.


4. Handle auth carefully

Common patterns:

  • Cookie-based session for browser apps
  • Token exchange or delegation for service-to-service auth
  • Propagate user identity to downstream services securely

Avoid exposing internal service credentials to the frontend.


5. Add caching where it makes sense

Cache:

  • Static/reference data
  • Frequent read-only data
  • Expensive aggregated responses

Be careful with:

  • User-specific data
  • Cache invalidation
  • Sensitive information

6. Make the BFF resilient

Add:

  • Timeouts
  • Retries with backoff
  • Circuit breakers
  • Fallback responses
  • Bulkheads / concurrency limits

The BFF should degrade gracefully if one downstream service is slow or unavailable.


7. Normalize errors

Don’t leak internal service errors directly to the frontend.

Instead, convert them into consistent responses:

{
  "error": {
    "code": "CHECKOUT_UNAVAILABLE",
    "message": "Checkout is temporarily unavailable"
  }
}

8. Log and observe

Track:

  • request IDs / correlation IDs
  • downstream latency
  • error rates
  • cache hit rates
  • payload sizes

This is critical because BFFs often become performance bottlenecks.


Technology choices

A BFF can be built with almost any backend stack:

  • Node.js/TypeScript — very common for web BFFs
  • Java/Spring Boot
  • .NET
  • Go
  • GraphQL server — sometimes used as a BFF layer
  • NestJS / Express / Fastify for Node
  • Next.js / Remix / Nuxt server routes if the BFF is colocated with the frontend

REST vs GraphQL vs gRPC

  • REST BFF: simpler, explicit endpoints, easy to debug
  • GraphQL BFF: great for flexible UI querying, but more complexity
  • gRPC BFF: usually internal; less common for browser-facing APIs

A BFF can even expose REST to the frontend and use gRPC internally.


Example: simple Node.js BFF

import express from "express";
import fetch from "node-fetch";

const app = express();

app.get("/dashboard", async (req, res) => {
  try {
    const [userRes, ordersRes, notificationsRes] = await Promise.all([
      fetch("http://user-service/me"),
      fetch("http://order-service/recent"),
      fetch("http://notification-service/recent")
    ]);

    const [user, orders, notifications] = await Promise.all([
      userRes.json(),
      ordersRes.json(),
      notificationsRes.json()
    ]);

    res.json({
      user,
      orders,
      notifications
    });
  } catch (err) {
    res.status(502).json({
      error: {
        code: "BFF_UPSTREAM_ERROR",
        message: "Unable to load dashboard"
      }
    });
  }
});

app.listen(3000);

Common mistakes

  • Making the BFF a “mini monolith” with too much business logic
  • Designing endpoints around backend services instead of frontend screens
  • Duplicating logic that should live in core services
  • Not using timeouts/retries
  • Overusing the BFF for every possible API call
  • Letting it become a bottleneck without caching/observability

Rule of thumb

Use a BFF when:

  • one frontend has unique needs
  • multiple backend services must be composed
  • you want to simplify client code

Don’t use a BFF if:

  • your app is tiny and a simple API is enough
  • the BFF would just proxy calls without adding value
  • you’re using it to hide poor service boundaries instead of fixing them

If you want, I can also give you:

  1. a reference BFF architecture,
  2. a Node/TypeScript starter template, or
  3. a step-by-step design for a real app like e-commerce or SaaS.

Observation history

See 1 earlier observation

Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (2 observations for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.