BFF Deployment Patterns

BFF Deployment Patterns

BFF deployment patterns describe the topological relationship between the Angular SPA, the BFF service, downstream microservices, and infrastructure components (CDN, load balancer, API gateway). The right topology depends on team structure, scale requirements, and whether multiple client types share the BFF.

Topology 1: Standalone BFF Service

The BFF is deployed as an independent service behind a load balancer. This is the baseline deployment.

Internet
   |
   v
Load Balancer
   |
   v
BFF (Spring Cloud Gateway)
   |            |            |
   v            v            v
Service A    Service B    Service C
                |
                v
             Redis (session store)

Characteristics:

  • BFF is independently deployable and scalable
  • Session state externalised to Redis — multiple BFF instances are stateless
  • Downstream services are not internet-accessible; they sit on a private network segment
  • Load balancer handles TLS termination (or BFF does — prefer LB for cert management)

Best for:

  • Multiple Angular apps sharing one BFF with different route prefixes
  • BFF containing significant custom aggregation logic that warrants its own service
  • Teams that want a clear deployment boundary

Topology 2: BFF at the Edge (CDN + BFF)

Angular static assets are served from a CDN. API calls go to the BFF. From the browser's perspective, both share the same origin — eliminating CORS entirely.

Browser
   |
   +---(static assets)---> CDN (Angular build)
   |
   +---(API calls /api/*)--> Load Balancer --> BFF --> [Services]

The CDN and the BFF are configured to respond on the same domain (e.g., app.example.com). The CDN routes /api/* to the origin (BFF); all other paths serve the Angular index.html or static assets.

app.example.com/          → CDN: serves index.html
app.example.com/assets/*  → CDN: serves JS/CSS bundles
app.example.com/api/*     → CDN passes through to BFF origin

Characteristics:

  • Zero CORS configuration needed — same origin throughout
  • CDN caches static assets; BFF handles only dynamic API traffic
  • Angular HttpClient uses relative URLs (/api/...) — no absolute URL configuration needed
  • Session cookies are SameSite=Strict with no cross-origin complications

Best for:

  • Production deployments where eliminating CORS is a security priority
  • Angular SPAs where frontend performance (CDN caching) matters

Topology 3: BFF + API Gateway Layered

An infrastructure-level API Gateway (Kong, AWS API Gateway, Nginx) sits in front of the BFF. Each layer has a distinct responsibility.

Internet
   |
   v
API Gateway (Kong / AWS API GW)
  - TLS termination
  - Global rate limiting
  - API key authentication (for partner APIs)
  - DDoS protection
   |
   v
BFF (Spring Cloud Gateway / Spring Boot)
  - Client-specific aggregation
  - Angular-specific response shaping
  - Session management / OAuth2 token storage
  - Circuit breaking
   |
   v
[Microservices]

The division of responsibility is key:

  • API Gateway: infrastructure concerns — TLS, DDoS, global throttling, partner API key auth
  • BFF: application concerns — business-level aggregation, Angular data contracts, SPA session management

Characteristics:

  • Clear separation between infrastructure-level and application-level gateway concerns
  • BFF remains focused on the Angular client; generic concerns handled upstream
  • Multiple BFFs (web, mobile, partner) can sit behind the same API Gateway

Best for:

  • Enterprise environments with existing API Gateway infrastructure
  • Organisations with multiple client types (web, mobile, partner API) behind one entry point
  • Compliance requirements that mandate a dedicated infrastructure security layer

Topology 4: BFF Sidecar (Edge Computing)

The BFF is co-located with the Angular container — deployed as a sidecar or on a CDN edge node. Uncommon for Spring Boot BFFs.

[Edge Node]
  Angular (static server)
  BFF (sidecar)
       |
       v
   [Origin services]

Not recommended for Spring Boot BFFs: the Spring Boot runtime is too heavyweight for edge/sidecar deployment. This pattern is viable only with lightweight runtimes (Deno, Cloudflare Workers, Node.js). Spring Boot BFFs belong in Topology 1, 2, or 3.

When to Split BFFs

The core rule: one BFF per frontend team / frontend application.

Split when

  • A mobile app needs fundamentally different data shapes (nested vs flat DTOs, different pagination contracts)
  • A partner integration requires different authentication (API key vs OAuth2 PKCE) or different rate limits
  • Client SLAs differ significantly: internal admin dashboard vs customer-facing app
  • Release cadences diverge: mobile apps release slowly; web apps deploy weekly

Do not split when

  • It is just different pages or features of the same Angular app — use one BFF with different route prefixes
  • The team does not have capacity to maintain multiple BFFs — operational overhead is real (two sets of deployments, logs, alerts, circuit breaker configs)

Multi-BFF Monorepo Structure

bff-web/      ← serves the Angular web app (OAuth2 + session cookies)
bff-mobile/   ← serves the React Native app (JWT-based, stateless)
bff-partner/  ← serves partner integrations (API key auth, different rate limits)
shared-lib/   ← common DTOs, circuit breaker config, tracing setup, PageResponse<T>

shared-lib contains only the cross-cutting concerns — avoid putting business logic there. Each BFF owns its own response shapes and route definitions.

Redis Session Sizing for Horizontal Scale

In Topology 1 and 2, when the BFF scales horizontally, all instances must share session state:

spring:
  session:
    store-type: redis
    redis:
      flush-mode: on-save
      namespace: bff:session
  data:
    redis:
      host: ${REDIS_HOST:localhost}
      port: 6379

Session TTL should match the OAuth2 token TTL (typically 1 hour). Redis Sentinel or Redis Cluster handles availability for production deployments.