System Design Cases
BFF (Backend For Frontend)
BFF (Backend For Frontend) concept page: per-client backend layer (web BFF, mobile BFF, GraphQL gateway alternative, partner public API) sitting between clients and domain microservices. Three scenarios: web BFF aggregates 5 microservice calls into single typed response with edge cache; mobile BFF returns lighter payload (3KB vs 12KB); GraphQL gateway alternative with DataLoader. Plus anti-patterns scenario for timeouts/circuit breakers. Includes ADR comparing BFF per-client vs single GraphQL gateway vs API Gateway.
Backend for Frontend: client-specific composition without misplaced authority
BFF — backend component aligned with one frontend experience. Он может агрегировать вызовы, адаптировать payload и в browser architecture держать OAuth tokens вне JavaScript, но остаётся дополнительным deployable hop с собственными SLO и attack surface.
BFF не должен становиться общим доменным монолитом: бизнес-инварианты и object-level authorization остаются у authoritative services. Разделение имеет смысл, когда web и mobile действительно имеют разные change cadence, payload или security needs.
Проверяемые утверждения
- Отдельный BFF на интерфейс уменьшает конфликт client-specific требований, но увеличивает operational overhead и вероятность дублирования.
- Browser BFF может быть confidential OAuth client и связать server-side tokens с защищённой cookie session, не выдавая access/refresh tokens browser JavaScript.
- Cookie-authenticated BFF требует защиты от CSRF; SameSite — defense in depth, не универсальная замена anti-CSRF token и Origin checks.
- Parallel aggregation снижает сумму latency только до критического пути; fan-out всё равно умножает downstream load и failure probability.
Границы и компоненты
| Компонент | Роль в модели |
|---|---|
| Web Browser | secure session request |
| Mobile Client | mobile API request |
| Web BFF and Session | secure session request; confidential OAuth client; authorized read; authorized read; fan-out spans |
| Mobile BFF | mobile API request; compact read; mobile command; fan-out spans |
| Authorization Server | confidential OAuth client |
| Catalog Service | authorized read; compact read |
| Orders Service | authorized read; mobile command |
| Deadline and Fan-out Telemetry | fan-out spans; fan-out spans |
Сценарии
Aggregate a web view under one deadline
The web BFF authenticates the session and starts independent catalog and order reads in parallel with child deadlines shorter than the client deadline.
Проверяемый исход: The response contract identifies complete, partial and unavailable sections; optional failure never masquerades as an empty business result.
Tailor a bandwidth-aware mobile response
The mobile BFF asks for only fields and page size needed by the mobile experience, without changing domain rules in downstream services.
Проверяемый исход: The payload and release cadence are client-specific while order authorization and invariants remain authoritative downstream.
Keep OAuth tokens out of browser JavaScript
The web BFF acts as the confidential OAuth client. It completes the authorization code flow, stores tokens server-side and binds them to a Secure, HttpOnly cookie session.
Проверяемый исход: Browser JavaScript receives neither access nor refresh token; cookie requests still pass CSRF and session-binding controls.
Contain a downstream timeout
Orders exceeds its child deadline while catalog succeeds. The BFF cancels remaining work, follows the documented degraded contract and preserves enough telemetry to diagnose the dependency.
Проверяемый исход: The client sees explicit partial availability, retry policy does not amplify the timeout, and the BFF thread/connection pool remains bounded.
Failure, concurrency и evolution checklist
- Propagate a client deadline and allocate smaller child budgets; otherwise BFF work can continue after the caller has gone away.
- Bound concurrency and retries per downstream. Retry only idempotent/safely keyed operations and include retry load in capacity tests.
- Define partial-response semantics per field. Timeout, forbidden, not-found and empty collection are not interchangeable.
- Deploy BFF and frontend contracts compatibly; use additive changes, consumer tests, canary and rollback rather than lock-step hope.
Security и privacy
- For the full browser BFF pattern, store OAuth tokens server-side and use Secure, HttpOnly cookies with a narrow Path/Domain and intentional SameSite policy.
- Protect state-changing cookie requests with CSRF token and/or strict Origin validation appropriate to the deployment; SameSite remains defense in depth.
- Validate forwarded headers at the trusted proxy boundary, authorize every downstream resource, and never treat a BFF-supplied user ID as proof by itself.
- Redact tokens, cookies and personal payloads from aggregate traces; use correlation identifiers without turning them into bearer credentials.
Метрики, формулы и допущения
downstream_rps_i = frontend_rps × mean_calls_i_per_request; total backend work is the sum across dependencies even when calls run in parallel.response_latency ≈ ingress + max(parallel_dependency_paths) + composition + egress; sequential prerequisites remain additive.- If independent dependency success probabilities are an explicit model, all-required success is
Π p_i; correlation makes that product optimistic and must be measured. - Capacity includes retry amplification:
attempt_rps = logical_rps × mean_attempts_per_call, bounded by retry budget and concurrency limits.
Числа и bounds выше действуют только при названных units, population и assumptions. Ни паттерн, ни browser API сами по себе не задают SLA, capacity или correctness.
Решения для production review
- Create separate BFFs only for materially different experience contracts or team cadence; identical clients may share a simpler gateway/API.
- Keep client composition, payload adaptation and browser session mechanics in BFF; keep durable domain invariants in owning services.
- Publish dependency budgets, degraded behavior, ownership and on-call responsibility before adding the extra hop.
Первичные и официальные источники
- https://learn.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends
- https://www.rfc-editor.org/rfc/rfc10017.html
- https://www.rfc-editor.org/rfc/rfc9700.html
- https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
Scope note
Диаграмма показывает full browser BFF и отдельный mobile BFF. Она не утверждает, что GraphQL всегда устраняет BFF, что cookie session автоматически безопасна или что каждый экран требует отдельного сервиса.