PATTERN Cited by 1 source
Business-Logic-Free Data Aggregation Layer¶
When to use¶
You are building an API gateway / aggregation layer (BFF, GraphQL, REST facade) that sits between N frontend clients and M backend microservices, and you want:
- Long-term operational simplicity for the aggregation layer.
- Clean ownership boundaries — one team owns the aggregation layer, many teams own the downstream services.
- Ability for domain teams to evolve their platform- specific behaviour independently of the aggregation layer.
- Protection against the aggregation layer slowly accumulating everyone's logic and becoming a God Component.
The pattern¶
Declare the aggregation layer has no business logic, only:
- Schema / shape transformation.
- Cross-domain composition (fan-out to N services, assemble the result).
- Cross-cutting concerns uniform across domains: auth, rate limiting, observability, caching, request coalescing.
All domain-specific logic and all platform-specific logic (Web vs App vs partner API) live in downstream presentation-layer backends — one or more services per domain that expose presentation-ready data tailored to the caller.
clients (Web, iOS, Android, …)
│
▼
┌───────────────────────────────┐
│ aggregation layer │
│ ┌─ schema/shape │
│ ┌─ cross-domain composition │
│ ┌─ auth + observability │
│ ✗ NO business logic │ ← enforced principle
│ ✗ NO platform steering │
└──────────────┬────────────────┘
▼
presentation-layer backends
(domain + platform logic here)
│
▼
domain microservices
Canonical wiki instance: Zalando UBFF¶
Zalando's Unified Backend-For-Frontends GraphQL declares this principle explicitly (Source: sources/2021-03-03-zalando-how-we-use-graphql-at-europes-largest-fashion-e-commerce-company):
"Our approach with GraphQL has been to avoid any platform or domain specific logic in the GraphQL layer and instead let the domain specific teams drive this via presentation layer backend services. This allows us to keep a business logic agnostic data-aggregation layer which serves frontend developers and also helps in operational maintenance."
And:
"The GraphQL layer has a 'No Business Logic' principle, which allows domain specific backend APIs to steer domain or platform (Web vs. App) specific content on their own."
This principle is what makes the UBFF scalable across 12+ domains and 200+ developers without the aggregation layer becoming a place where every team ships features.
What the principle buys you¶
- Operational simplicity at the aggregation layer. The layer is easier to reason about, review, test, and debug because it only does aggregation.
- Team autonomy on business rules. Domain teams can change delivery-window computation, pricing rules, platform-specific personalisation, etc., without touching the aggregation layer's code. Platform differences (Web wants more data, mobile wants less) also live downstream.
- Cross-cutting concerns stay uniform. Auth, observability, rate limits, caching are the aggregation layer's job; they don't get domain-specific exceptions because "this team needed to ship X."
- Prevents the God Component slide. Without this principle, a shared aggregation layer accumulates everyone's special-case logic and becomes impossible to own.
What this principle costs¶
- More services to operate. You now have the aggregation layer plus N presentation-layer backends, not just one aggregation layer with logic.
- More hops per request. A client request traverses: client → aggregation → presentation backend → domain backend. Each hop adds latency.
- Aggregation-layer "clever composition" is tempting. Reviewers and owners must actively enforce the principle; one-off "just this once" additions of business logic erode the contract.
- Clear contract for presentation-layer backends required. "Presentation layer" becomes a known architectural tier; domain teams need to understand they own it.
Where the boundary gets blurry¶
- Data reshaping vs logic. Is flattening nested data "aggregation" or "logic"? The pattern says "aggregation"; the line isn't sharp.
- Sensible defaults. If field A is null, default to field B — is that aggregation or logic? The pattern says "push to presentation-layer"; operationally this adds hops.
- Cross-cutting rules that are business logic. Is tenant-visibility filtering a cross-cutting concern or domain logic? Usually cross-cutting at the auth layer, but the line is contested.
Contrast with adjacent patterns¶
- Logic-heavy BFF — the classic per-surface BFF actively owns platform-specific logic. That approach has the Conway's-Law-shaped pathologies; this pattern is the opposite design choice.
- patterns/graphql-unified-api-platform — the umbrella. This pattern is a specific discipline applied on top: the unified GraphQL API also has no business logic.
Seen in¶
- sources/2021-03-03-zalando-how-we-use-graphql-at-europes-largest-fashion-e-commerce-company — Zalando's UBFF; the principle is stated twice in the post as a load-bearing commitment.
Related¶
- patterns/unified-graphql-backend-for-frontend — where this principle is typically enforced
- patterns/graphql-unified-api-platform
- systems/zalando-graphql-ubff
- concepts/backend-for-frontend
- concepts/separation-of-concerns — the deeper principle this instantiates