BFF Pattern

BFF Pattern (Backend For Frontend)

A dedicated server-side aggregation layer, one per distinct client type, that owns the API contract for that client and shields downstream microservices from client-specific concerns.


Core Idea

The BFF pattern is the recognition that API shape is UI logic. The structure, fields, and granularity of data returned to a client exists to serve that client's specific rendering needs — and therefore the server-side code that produces it should be owned by the team responsible for that client.

Instead of one shared backend API that all clients call, each client type (web app, mobile app, partner API) gets its own dedicated backend service. That backend is free to:

  • Aggregate multiple downstream service calls into one response
  • Transform data shapes to exactly what the client needs
  • Implement client-specific caching and performance optimizations
  • Handle client-specific authentication flows
  • Be deployed independently of other BFFs

The pattern was formalized by Sam-Newman around 2015, drawing on prior art from SoundCloud's engineering team and Netflix's device-specific API work.


Key Principles

  1. One BFF per client type — a BFF that serves two distinct client types is a generic API and loses the core benefit
  2. BFF is owned by the frontend team — the mobile team owns the Mobile BFF; the web team owns the Web BFF; organizational alignment is the primary benefit
  3. BFF aggregates, it does not own business logic — domain logic belongs in the downstream microservices; the BFF orchestrates, not decides
  4. BFF is a backend, not a framework — it is a regular service (e.g., a Spring Boot application) with no special runtime; the "pattern" is organizational and structural
  5. BFF sits behind an API-Gateway-Pattern — cross-cutting infrastructure concerns (TLS, rate limiting, routing) belong in the gateway, not in each BFF

How It Works

A client makes a single request to its BFF (e.g., GET /home-screen). The BFF:

  1. Validates and authenticates the request (client-specific auth strategy)
  2. Fans out to N downstream microservices in parallel (User Service, Feed Service, Notification Service)
  3. Awaits all responses (with timeout and circuit-breaker protection)
  4. Aggregates, transforms, and filters the responses into a single client-optimized payload
  5. Returns one response to the client
Client ──> BFF ──┬──> User Service     ──┐
                 ├──> Feed Service     ──┤ (parallel calls)
                 └──> Notification Svc ──┘
                         |
                  [aggregate + transform]
                         |
                  Client-specific response

In Spring Boot, this fan-out is implemented with Spring WebFlux (Mono.zip / Flux composition) to avoid blocking threads during downstream calls.


When to Use BFF

  • Multiple client types with meaningfully different data needs (web vs. mobile vs. partner)
  • Frontend teams want autonomy over their server-side aggregation layer
  • Different clients require different auth strategies
  • Mobile clients need bandwidth-efficient, pre-aggregated responses
  • You want to avoid if (clientType == MOBILE) proliferation in shared backends

When NOT to Use BFF

  • You have only one client type (just build a single backend)
  • The team is small and the overhead of maintaining multiple services outweighs the benefit
  • Client data needs are nearly identical (a shared API with optional fields is simpler)
  • You need a public developer platform with many unknown consumers (GraphQL or a well-documented REST API is better)

BFF vs Other Patterns

BFF vs Generic API Gateway

They are complementary. The API-Gateway-Pattern handles cross-cutting infrastructure (TLS, rate limiting, auth token validation, routing). The BFF handles client-specific aggregation and transformation. The canonical architecture is:

Internet → API Gateway → [Web BFF | Mobile BFF | Partner BFF] → Microservices

BFF vs GraphQL

Both solve "different clients need different data." GraphQL solves it with a flexible query language on one endpoint. BFF solves it with separate services, one per client.

BFFGraphQL
Best forSeparate teams, complex orchestrationRapid iteration, many consumers
FlexibilityVia code changesVia query changes (no deploy)
OwnershipPer-team ownershipShared schema
Learning curveLow (just Spring Boot)Higher (schema design, resolvers)
Can combine?Yes — BFF can expose a GraphQL endpointYes — BFF in front of GraphQL federation

Common Misconceptions

  • "BFF is just an API Gateway" — An API Gateway routes and applies cross-cutting concerns; a BFF aggregates and transforms for a specific client. Different tools, different jobs.
  • "BFF adds unnecessary complexity" — For teams with multiple distinct client types, BFF removes complexity by eliminating conditional branching in shared backends and decoupling deployment cycles.
  • "The BFF must be in the same language as the frontend" — No. The BFF is a server-side service. It can be written in any language. The recommendation is that the team who owns the BFF can choose their language — which often means the mobile team might choose Go or Node, while a Java shop might stick with Spring Boot.
  • "BFF is only for microservices" — BFF is most valuable in microservices, but the aggregation concern exists in any multi-client scenario.

Why It Matters

BFF is a prerequisite pattern for the OAuth2-BFF-Pattern (Token Handler pattern), which keeps OAuth2 tokens server-side and out of browser JavaScript. The BFF's position as a server-side intermediary between the browser and downstream services is what makes this security pattern possible.

In a Spring Boot context, understanding BFF is foundational for:

  • Spring-Cloud-Gateway configuration (when the gateway itself acts as a thin BFF)
  • Reactive-Programming-WebFlux (non-blocking fan-out inside the BFF)
  • Circuit-Breaker-Pattern (Resilience4j protecting the BFF from downstream failures)

ConceptRelationship
API-Gateway-PatternSits in front of BFF; handles cross-cutting concerns
Sam-NewmanFormalized and named the BFF pattern
OAuth2-BFF-PatternSecurity pattern enabled by BFF's server-side position
Spring-Cloud-GatewayCommon implementation technology for BFF in Java ecosystem
Service-MeshOperates below BFF; handles mTLS and tracing between services
Contract-TestingUsed to verify BFF → downstream service API contracts
  • REST-API-Design — BFF contracts are typically REST APIs; REST versioning lifecycle and RFC 9457 error contracts apply directly to the BFF-to-client surface
  • GraphQL-API-Design — BFF is a common pattern for exposing a GraphQL endpoint to a frontend client; the BFF vs GraphQL comparison is documented in both notes
  • Session-Management — BFF manages server-side sessions (httpOnly cookie, Redis store); Session-Management covers the full session lifecycle including fixation prevention and SameSite attribute selection

Sources

  • Sam Newman, "Pattern: Backends For Frontends" — samnewman.io
  • Sam Newman, "Building Microservices" 2nd ed. (O'Reilly, 2021)
  • Phil Calçado, SoundCloud Engineering Blog — BFF discovery in practice
  • Netflix Tech Blog, "Optimizing the Netflix API" — per-device backend evolution
  • Thoughtworks Technology Radar Vol. 14 (2016) — BFF listed as "Adopt"