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
HttpClientuses 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: 6379Session TTL should match the OAuth2 token TTL (typically 1 hour). Redis Sentinel or Redis Cluster handles availability for production deployments.
Backlinks
- BFF-Pattern — deployment is the operational realisation of the BFF pattern
- BFF-For-SPA — Topology 2 (CDN) eliminates the CORS problem for SPAs
- Spring-Cloud-Gateway — the BFF runtime in all three recommended topologies
- OAuth2-BFF-Pattern — session-based token storage requires Redis in all topologies
- P6-BFF-Angular-Integration — ANG-06 covers deployment topology in the Angular context