← Back to API and Web Development

GraphQL Adoption Patterns

Four GraphQL adoption patterns, from API wrappers to federated ownership.

Teams rarely jump straight from REST endpoints to a large federated GraphQL estate. Most adoptions move through a few recognisable patterns, each solving a real problem while introducing a new operational cost. The right pattern depends less on fashion and more on who owns the data, how many clients you support, and where aggregation logic currently lives.

1. Client-side GraphQL over existing APIs

The lightest entry point is to put a GraphQL layer in front of existing REST or RPC APIs without changing the underlying services. Clients get one schema, one query language, and a cleaner way to ask for exactly the fields they need.

This improves developer experience quickly, especially when a page needs data from several services. The server-side resolver layer can hide awkward legacy contracts and combine multiple calls into one response. The tradeoff is that the GraphQL server becomes an aggregation tier. If each field resolver independently calls downstream services, latency and N+1 query problems appear quickly. This pattern works best when the team wants a better API surface first and can tolerate an orchestration layer sitting above existing backends.

2. GraphQL with BFFs

A backend-for-frontend gives each client type its own API layer. A mobile app may need compressed payloads and a few large compound queries, while a web client may prefer more granular access. GraphQL fits BFFs well because the schema can be shaped around a specific product surface rather than a generic enterprise model.

The benefit is local optimisation. Each BFF team can evolve fields, caching, and authorisation rules around the needs of one client family. The cost is duplication. Shared entities such as User or Product can drift across BFFs, and multiple teams may write similar resolver logic against the same downstream services. BFFs are a strong choice when client needs genuinely differ and product teams already operate independently.

3. A monolithic GraphQL server

In the monolithic pattern, one GraphQL codebase exposes a single schema for multiple clients. This centralises discovery, tooling, and governance. Cross-cutting concerns such as authentication, persisted queries, complexity limits, and observability are easier to standardise in one place.

A monolith is often the best first serious GraphQL server because it keeps the model simple. One deployment owns the schema, the resolver patterns, and the release process. The problem appears with scale. As more teams contribute, schema ownership becomes blurry, release coordination slows, and a single repository can turn into an integration bottleneck. The graph is unified, but the operating model may not match the organisation.

4. Federation and the supergraph

Federation splits the graph into subgraphs owned by domain teams, then composes them behind a gateway. The payments team can own payment fields, the catalogue team can own product fields, and the identity team can own user fields, while clients still see one graph.

This aligns ownership with service boundaries and reduces the pressure to funnel every schema change through one central team. It also introduces a more sophisticated control plane. Teams must agree on entity boundaries, naming rules, schema change policies, and query cost controls. The gateway becomes mission-critical. Poorly designed subgraphs can still create chatty request plans or hide slow downstream dependencies. Federation works well when multiple domains genuinely need independent evolution, not simply because the word sounds modern.

The common mistake is treating GraphQL adoption as a binary decision. It is usually a progression. Start by fixing the problem you actually have: too many client round trips, duplicated view logic, inconsistent APIs, or organisational contention. Then choose the smallest GraphQL pattern that solves that problem. A graph is useful when it reduces accidental complexity. It is not useful when it merely relocates it.