API · Graphql

GraphQL Federation vs BFF

GraphQL Federation vs BFF is the work that makes the systems talk. The API is the contract between the producer and the consumer; the contract is what determines whether the.

John Kihiu12 min read

Both patterns solve the same underlying problem — a client needs data shaped differently than any single backend service exposes it — but they solve it at different altitudes. A Backend-for-Frontend is a purpose-built aggregation layer per client team; GraphQL Federation is one shared graph that many backend teams contribute to. Picking between them is a team-topology decision as much as a technical one.

What each pattern actually is

A BFF is an ordinary backend service, usually owned by the team that owns a specific client (mobile app, web app, partner integration). It calls whatever downstream REST, gRPC, or GraphQL services it needs, reshapes and combines the responses in application code, and exposes an API tailored to that one client's needs. There's no shared schema contract across BFFs — the mobile BFF and the web BFF can diverge freely.

Federation is a single GraphQL schema assembled from subgraphs, each owned by a backend domain team, composed by a gateway/router into one supergraph that any client can query. The schema is the contract, and it's shared: a field added by the orders subgraph is immediately queryable by every client, not just the one that asked for it.

Operational cost

Federation isn't free to run. You need a gateway or router, a composition step (checking that subgraph schema changes don't break the supergraph) wired into CI, and a discipline around versioning subgraphs together since they all feed one contract. Get composition wrong and you can break queries for clients that have nothing to do with the subgraph that changed.

A BFF avoids all of that — it's just another service with its own deploy pipeline, no shared schema to compose, no cross-team contract to negotiate. The cost shows up elsewhere: if you have three BFFs doing similar aggregation against the same downstream services, that orchestration logic (and its bugs) gets written and maintained three times.

Federation without cross-team schema discipline is worse than no federation

If every subgraph team ships breaking changes without checking against the supergraph, you've built a distributed monolith with extra infrastructure. The composition/CI gate isn't optional overhead — it's the thing that makes federation safer than stitching by hand.

Team topology fit

Federation fits an org where many teams each own a slice of one conceptual domain graph — a catalog team, an inventory team, a reviews team, all contributing fields to a shared Product — and where multiple client teams all want to query across those domains without each one re-implementing the joins. A BFF fits an org with a handful of client teams, each with genuinely different shaping needs (a partner API wants a flattened response, a mobile app wants an aggressively trimmed payload for battery/bandwidth), where forcing everyone onto one shared schema would mean constant negotiation over field names nobody but one client cares about.

Query execution: planning vs hand-written orchestration

Federation resolves a query by generating a query plan: the gateway works out which subgraphs to call, in what order, and fans requests out — often in parallel — based on the entity keys returned from earlier calls. That fan-out is automatic but adds a hop (client → gateway → N subgraphs) and the query planner itself is a piece of infrastructure whose behavior you don't hand-write.

A BFF's orchestration is just code: you write the sequence of downstream calls, decide what runs in parallel, and handle partial failures explicitly. That's more manual work per endpoint, but it's also more legible — there's no query planner to reason about when something is slow, only the orchestration function itself.

DimensionBFFFederation
Schema ownershipPer client team, siloedShared, split by domain
Duplication riskHigh across BFFsLow — one schema, many contributors
Infra to runJust the BFF serviceGateway/router + composition pipeline
Change safety netWhatever the BFF team buildsComposition checks in CI
Best fitFew clients, divergent shapesMany teams, one domain graph

A pragmatic starting point

Most organizations are better served starting with a BFF, or even no aggregation layer at all, and only reaching for federation once schema ownership sprawl becomes a real, felt problem — several teams independently building similar aggregation logic against the same underlying services, or clients waiting on one team to add fields to a schema they don't own. Federation is a good answer to that specific problem. It's a poor default, because it front-loads gateway infrastructure and cross-team schema governance before you know whether you need either.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.