System Design Space
Knowledge graphSettings

Updated: May 7, 2026 at 5:18 PM

Frontend data layer: REST, GraphQL, BFF, and orchestration

medium

The boundary between UI and backend: REST/GraphQL/BFF, loaders, retries, partial failures, aggregation, and contract evolution in the client data layer.

The frontend data layer becomes an architectural pain point as soon as a screen stops reading one endpoint and starts assembling user experience from multiple services, partial failures, and different response speeds. At that point, the choice between REST, GraphQL, BFF, and route-level loaders starts shaping UX directly.

The chapter is valuable because it treats data flow as architecture rather than a set of fetch calls. What matters is not only how data is loaded, but where aggregation happens, who owns retries, how stale and partial states are handled, and what contract remains between UI and backend.

For design reviews, this is useful because it lets you discuss client data in terms of boundaries, orchestration, and failure handling instead of reducing everything to transport choice or a request library.

Practical value of this chapter

Design in practice

Turn guidance on contracts between UI and backend, orchestration, and resilient data flow into concrete decisions for composition, ownership, and client-runtime behavior.

Decision quality

Evaluate architecture through measurable outcomes: delivery speed, UI stability, observability, change cost, and operating risk.

Interview articulation

Structure answers as problem -> constraints -> architecture -> trade-offs -> migration path with explicit frontend reasoning.

Trade-off framing

Make trade-offs explicit around contracts between UI and backend, orchestration, and resilient data flow: team scale, technical debt, performance budget, and long-term maintainability.

Context

REST, gRPC, and GraphQL

Transport choice is only useful as part of a larger conversation about UI-facing contracts, retries, and aggregation.

Читать обзор

The data layer defines whether a screen can stay predictable in a fragmented backend landscape. Once UI talks to multiple services, handles partial failures, and still needs to deliver a compact view model quickly, an explicit architectural layer between the screen and transport details becomes necessary.

In mature frontend systems, data flow is discussed not only through the word fetch, but through contracts, orchestration, retries, stale states, and ownership.

Integration models

REST + route loaders

A straightforward option for predictable screens and explicit boundaries. It works well when a screen needs a limited number of requests and the contract evolves steadily.

GraphQL

Useful when UI assembles data from multiple domains and frequently changes response shape. The cost is schema governance, client-cache complexity, and protection against overly expensive queries.

BFF / UI orchestration layer

Needed when the backend landscape is too fragmented or when UI should receive a compact view model shaped around auth, localization, and product-specific aggregation.

Hybrid approach

One product often uses several modes at once: BFF for critical flows, GraphQL for exploration-heavy surfaces, and REST for stable operational screens.

Related

Customer-Friendly API

A strong frontend data layer almost always depends on API shape that is convenient for the product, not only for service infrastructure.

Open chapter

Rules for resilient data flow

Partial failure must be designed into UX

If one dashboard widget is unavailable, the rest of the screen does not have to collapse. The data layer should distinguish hard failure, stale fallback, and incomplete response.

Retry policy belongs to more than the transport layer

Retry behavior depends on user intent, idempotency, loading cost, and whether stale data can be shown safely instead of aggressive refetching.

A view model is usually more useful than raw service contracts

Frontend wins when it receives an API shape close to the screen. Otherwise orchestration spreads across hooks, selectors, and component trees.

Data contracts must evolve like public APIs

BFFs, GraphQL schemas, and typed clients need deprecation policy and versioning, otherwise screen migration starts blocking release cadence across teams.

Questions before choosing BFF or GraphQL

  • How many backend domains one screen must assemble and where aggregation is cheapest.
  • Whether the UI needs a stable view model or current service DTOs are already close enough to the screen.
  • How critical partial response, cancellation, optimistic update, and background refresh really are.
  • Who owns schema evolution: frontend platform, the product team, or a backend team with a UI-facing contract.

Main anti-pattern

Leaving orchestration at the component level means one screen ends up knowing the internal shape of many backend domains. That UI quickly loses predictable error handling, typed contracts, and the ability to evolve safely.

Related chapters

Enable tracking in Settings