---
topic: system-design
author: Crashtech Editorial
published: Nov 14, 2026 · read: 5 min
---

Backends for Frontends, and What Comes After: Value-Added Services and Domain Gateways

BFFs fix client sprawl, then duplicate authorization logic across themselves. The three-layer fix: edge, value-added services, and per-domain gateways.

– –

Breaking up a monolith moves complexity, it does not delete it. The monolith’s single API hid how many things it took to build a track page. Once the services are separate, every client must know. The architecture question is where that knowledge should live, and the honest answer changes as you grow.

Step one: a gateway per client type

A Backend for Frontend is an API gateway dedicated to one kind of client. A mobile BFF for iOS and Android, a web BFF for the site and embeds, and separate ones for public and partner APIs. All external traffic passes through one of them.

Each BFF owns edge concerns: authentication, rate limiting, header sanitisation and cache control. Shared edge code lives in an internal library that rolls out to every BFF quickly, and teams outside the platform group contribute code under review by a core team, the “inner source” model.

What it buys

Autonomy biggest win
Clients want different things. A mobile client may prefer fewer, larger responses with embedded entities to save round trips, while a web front end prefers fine-grained ones. Each BFF optimises for its client without compromise.
Smaller blast radius resilience
A bad deploy takes down one BFF in one zone, not the whole platform. The mobile BFF failing does not take down web.
Faster shipping confidence
Autonomy plus isolation makes frequent releases routine. Main BFFs can deploy several times a day.
No client-side orchestration simplicity
Clients make one call, and the BFF fans out to services. This matters most for third parties who cannot be told to rewrite their integration.

Step two: the BFF layer starts to rot

Every one of those wins has a mirror image.

ProblemHow it happens
Logic creepFoundational services are tiny and CRUD-only, so all feature integration lands in the BFF. Clients also push their own logic upstream (“it is just the client’s backend”), such as pagination
DuplicationThe same rule gets implemented in several BFFs, and the copies drift as each evolves
Authorization driftA visibility rule needs data from Track and Playlist services, so each BFF fetches both and re-implements the check. One slips
ProliferationA BFF for every small use case multiplies deploys, on-call and maintenance. Full autonomy is also an illusion: front-end and back-end people must still collaborate
Duplicated authorization is a security bug waiting to happen

Access rules must exist in exactly one place. If two codebases independently decide who may see a track, they will eventually disagree, and the disagreement is a data exposure. This was the strongest argument for the next layer.

Step three: value-added services own the aggregates

The fix was a middle tier. The new shape has three layers:

  Clients
     |
  EDGE SERVICES          (BFFs: auth, rate limit, caching, response shaping)
     |
  VALUE-ADDED SERVICES   (own core aggregates and their rules)
     |
  FOUNDATIONAL SERVICES  (low-level building blocks)

A value-added service borrows vocabulary from domain-driven design: a domain bounds the concern, entities have identity and lifecycle, value objects describe them, and aggregates group related entities. A Track service and a Playlist service build these aggregates once, including the context-dependent rules. The Track service, for example, filters out tracks geo-blocked in a territory.

BFFs stop calling foundational services. They ask for aggregates, and all the shared code lives in one place.

Migrating without breaking anything

  1. Extract and document the logic

    Analyse what the BFFs actually do for the entity, and write it down. Hidden behaviour is the main risk.

  2. Pin it with tests

    Write automated tests to prove the new service matches the old logic, plus integration tests on response shape.

  3. Migrate endpoint by endpoint, comparing as you go

    Move endpoints (around fifty for playlists) to the new service while comparing old and new responses in production.

Advertisement

The costs of that layer

  • Fan-out. As features grow, an aggregate pulls from more services, and one request becomes many network calls.
  • One size fits no one. A feature only mobile uses is wasted work for web if the full aggregate is always built.

The answer to the second one is partial responses: the caller sends a field mask naming the parts it wants, and the service fetches and returns only those. The same endpoint serves lean and rich clients, and downstream calls shrink with the mask.

Step four: domain gateways

SoundCloud serves two audiences in one product: listeners consuming a catalogue, and creators uploading and distributing music. Those are different domains with different owners. One shared value-added service for both worked until coupling and complexity slowed everyone.

A domain gateway is a value-added service scoped to one business domain. The consumer gateway and the creator gateway each present their own view of an entity, owned by their own team, over the same foundational services. It acts as a facade and an anti-corruption layer: the domain’s model is protected from changes in the layers beneath and beside it.

It deliberately trades some duplication for autonomy, and is worth it only when domains have genuinely different access patterns and feature sets.

Which layer solves which problem

SymptomReach for
Clients juggle many servicesBFF
Different clients need different payload shapesBFF, or field masks on shared endpoints
Same business rule copied across gatewaysValue-added service
Authorization logic divergingValue-added service, single owner
One service serving two teams with conflicting needsDomain gateways
Too many gateways to operateMerge them. You have outgrown the pattern

Do

Keep BFFs thin: authentication, rate limits, shaping and caching. Put business and authorization rules in one service per aggregate. Add partial responses before adding endpoints. Introduce domain gateways only when two teams are really colliding.

Don't

Create a BFF per screen, or let each one reimplement visibility rules from raw service data. You will own the duplication and the security review.

Takeaway

Architecture here is a chain of fixes, each created by the last. Services broke the monolith, BFFs hid the services from clients, value-added services pulled duplicated rules out of the BFFs, and domain gateways stopped one service from serving two masters. Start with the smallest layer that solves your current pain, and add the next only when you can name the duplication it removes.

Advertisement

Frequently asked questions

What is a Backend for Frontend?

A dedicated backend gateway for one kind of client, such as mobile, web or partner API. It shapes responses to that client's needs and handles edge concerns like authentication, rate limiting and caching, so other clients are not forced into one compromise API.

What is the main risk of the BFF pattern?

Business logic leaks into the BFFs and gets duplicated across them. Authorization rules are the dangerous case: if three BFFs each implement them from raw service data, the copies drift and one eventually grants access it should not.

What is a value-added service layer?

A layer between edge gateways and low-level services that builds and owns core aggregates such as a track or playlist, including visibility and authorization rules. Every BFF asks it for the aggregate instead of re-assembling it from foundational services itself.

What does a field mask do in an API?

It lets a caller name exactly which fields of a resource it wants back, so a shared endpoint can serve a lean response to one client and a rich one to another. It controls payload size and downstream fan-out without creating a new endpoint per client.

Sources & further reading

/* Comments */