BFF Architecture — Map of Content
BFF Architecture — Map of Content
This MOC indexes all notes produced by the six-phase BFF Architecture research project. The research covers the Backend-for-Frontend pattern from first principles through to Angular-specific design, observability, testing, and deployment.
Capstone reference: BFF-Final-Synthesis Starter project: BFF Spring Boot Starter
1. What Is BFF and Why It Exists
The BFF pattern is an organisational and architectural pattern where each frontend client has a dedicated backend that owns the API contract for that client. Originating from Sam Newman's microservices work, it enables frontend team autonomy by decoupling the frontend data contract from downstream service APIs.
| Note | Role |
|---|---|
| P1-BFF-Foundations | Phase 1 research: pattern origin, trade-offs, architecture diagrams |
| BFF-Pattern | Atomic topic: the core pattern explained |
| API-Gateway-Pattern | Related pattern: BFF vs API Gateway distinction (they are not the same) |
| Sam-Newman | Originator: Sam Newman's 2015 BFF formulation |
| BFF-For-SPA | SPA-specific variant: session cookie auth model for Angular/React |
Key insight: the API Gateway handles infrastructure concerns (TLS, DDoS, rate limits); the BFF handles application concerns (aggregation, Angular-specific transformation, session management). They are complementary, not competing.
2. The Spring Boot Implementation Stack
Spring Cloud Gateway (SCG) is the reactive runtime for the BFF. Built on Spring WebFlux and Project Reactor, it provides non-blocking I/O essential for fan-out aggregation patterns.
| Note | Role |
|---|---|
| P2-Spring-Boot-BFF-Stack | Phase 2 research: SCG, reactive stack, dependency matrix |
| Spring-Cloud-Gateway | Atomic topic: SCG routing, predicates, filters, GatewayFilter |
| Project-Reactor | Atomic topic: Mono, Flux, operators for BFF aggregation |
| Reactive-Programming | Atomic topic: non-blocking I/O model, why it is required for BFF |
Dependency matrix highlights:
- Spring Boot 3.4.x + Spring Cloud 2024.0.x
spring-cloud-starter-gateway(notspring-boot-starter-web— servlet stack is wrong for BFF)spring-boot-starter-data-redis-reactive+spring-session-data-redisfor session
3. Implementation Patterns
The BFF's core job is aggregating data from multiple downstream services and transforming it into frontend-optimised shapes.
| Note | Role |
|---|---|
| P3-BFF-Implementation-Patterns | Phase 3 research: aggregation, transformation, error handling |
| Request-Aggregation | Atomic topic: Mono.zip for parallel fan-out, back-pressure, timeouts |
| Response-Transformation | Atomic topic: downstream DTO → Angular view model mapping |
| Circuit-Breaker-Pattern | Atomic topic: protecting BFF from downstream failures |
| Resilience4j | Atomic topic: Spring Boot 3.x circuit breaker implementation |
Key decisions:
Mono.zipis the correct operator for parallel aggregation — not sequentialflatMapchaining- Response transformation is the BFF's right to reshape data; the frontend never sees downstream service schemas
- Circuit breakers with fallbacks prevent downstream failures from cascading into BFF outages
4. Security Patterns
Security is where the BFF delivers the highest value for SPA clients. The BFF acts as a confidential OAuth2 client, holds tokens server-side, and communicates with Angular via httpOnly session cookie.
| Note | Role |
|---|---|
| P4-BFF-Security | Phase 4 research: OAuth2, CSRF, CORS, rate limiting, full security config |
| OAuth2-BFF-Pattern | Atomic topic: BFF as confidential OAuth2 client |
| Token-Relay-Pattern | Atomic topic: BFF forwarding access tokens to downstream services |
| BFF-For-SPA | Atomic topic: httpOnly cookie session — the only correct SPA token storage |
| PKCE | Atomic topic: Proof Key for Code Exchange for the auth code flow |
Non-negotiable rules:
- Never store tokens in
localStorageorsessionStorage— JavaScript-accessible = XSS-vulnerable - CSRF must remain enabled for any BFF using cookie-based auth — use
CookieServerCsrfTokenRepository.withHttpOnlyFalse() allowCredentials(true)in CORS config requires an explicitallowedOrigins(no wildcard)
5. Observability and Testing
A BFF is the single ingress point for the Angular app — observability gaps here make production debugging extremely difficult. Testing requires disciplined use of consumer-driven contracts to prevent stub drift.
| Note | Role |
|---|---|
| P5-BFF-Observability-Testing | Phase 5 research: tracing, metrics, logging, WireMock, contract testing |
| Distributed-Tracing | Atomic topic: W3C Trace Context, trace propagation across BFF and services |
| Micrometer | Atomic topic: Spring Boot 3.x tracing/metrics facade; replaces Spring Cloud Sleuth |
| Consumer-Driven-Contract-Testing | Atomic topic: BFF writes contracts; downstream verifies |
| WireMock | Atomic topic: HTTP stubbing for BFF integration tests |
Key decisions:
- Spring Cloud Sleuth is dead — Micrometer Tracing is the Boot 3.x replacement
MdcContextLifteris required to propagate MDC context through reactive chains (ThreadLocal does not propagate)@WireMockTestwithwiremock-spring-boot3.x (not the legacyWireMockRule)- Consumer-driven contracts: BFF team writes, downstream teams run verifier — breaks the build before deployment if the contract is violated
6. Angular Integration
The final phase covers how BFF design is driven by Angular component requirements: component-driven API contracts, pagination envelopes, real-time data via SSE, CORS elimination, versioning, and deployment topology.
| Note | Role |
|---|---|
| P6-BFF-Angular-Integration | Phase 6 research: all ANG-01 through ANG-07 requirements |
| Server-Sent-Events | Atomic topic: SSE from Spring Boot to Angular EventSource |
| BFF-Versioning | Atomic topic: URL path versioning strategy, SCG rewrite, N and N-1 |
| BFF-Deployment-Patterns | Atomic topic: 4 deployment topologies with trade-offs |
Key decisions:
- Design BFF endpoints around Angular component data needs, not microservice structure — one HTTP call per page/view
- SSE (
Flux<ServerSentEvent<T>>) is the correct real-time channel for notification and live feed use cases - Production: Angular and BFF share the same origin (CDN at edge) — CORS is irrelevant
- URL path versioning (
/api/v1/,/api/v2/) is pragmatic for BFF; maintain N and N-1 during deployments - One BFF per frontend team — split when mobile/web/partner have genuinely different data contracts or auth requirements
7. Synthesis and Reference
| Note | Role |
|---|---|
| BFF-Final-Synthesis | 5 key insights, decision framework, 3 common mistakes, future research |
| BFF Spring Boot Starter | Starter architecture: project structure, all dependencies, key config files |
8. Open Questions and Future Research
Surfaced during the six-phase research project — not yet investigated:
- gRPC streaming from BFF — mapping gRPC server-streaming (bidirectional flow control) to reactive
Fluxexposed as SSE; back-pressure across protocol boundary - GraphQL Federation as BFF alternative — Apollo Federation / Netflix DGS provide schema-level aggregation; when does this supersede a REST BFF?
- BFF in Kubernetes with service mesh — with Istio/Linkerd providing mTLS, observability, and circuit breaking at the mesh level, which BFF responsibilities remain unique?
- GraalVM native image for BFF — Spring Boot 3 native image trade-offs: reflection-heavy OAuth2 libraries, Redis serialisation, dynamic proxies
Key Architecture Decisions Documented Across All Phases
- Spring Cloud Sleuth is dead — Micrometer Tracing is the Boot 3.x replacement; never add Sleuth to a Boot 3.x project
- W3C Trace Context —
traceparent/tracestateheaders for end-to-end distributed traces - WebFlux MDC problem —
ThreadLocalMDC does not propagate in reactive chains; useMdcContextLifter - WireMock for integration tests —
wiremock-spring-boot+@WireMockTest(notWireMockRule) - Consumer-driven contracts — BFF as consumer writes contracts; downstreams verify against them
- Correlation ID filter —
CorrelationIdFilterasGlobalFilterwith order-1(first filter in chain) @ActiveProfiles("test")— disables Redis / OAuth2 for isolated integration tests- CSRF must stay enabled —
CookieServerCsrfTokenRepository.withHttpOnlyFalse()+ Angular reads cookie, sends as header - httpOnly session cookie — only correct token storage for Angular SPA; never localStorage
- One BFF per frontend team — organisational alignment is the foundational rule; technical split follows naturally