This chapter follows Limiting query depth and cost.
Monolith GraphQL servers eventually hit team boundaries: one schema repository, one deploy train, one on-call rotation. Federation splits ownership while preserving a single graph for clients.
Problem federation solves
Product domains (users, catalog, checkout) want autonomous deploys and private data stores, but mobile apps should still run one query spanning domains. Federation standardizes how subgraphs extend each other’s types without manual schema stitching scripts for every release.
Schema stitching versus federation
Stitching merges SDL from services with custom delegation logic—flexible but bespoke. Federation (Apollo Federation spec, Open Federation efforts) defines directives subgraphs use so a composer validates that the merged supergraph is coherent. A router (Apollo Router, Hive Gateway, Cosmo) plans fetches across subgraphs at runtime.
Subgraphs, supergraph, router
flowchart LR client[Client] router[Router] users[Users subgraph] products[Products subgraph] client --> router router --> users router --> products
- Subgraph — a GraphQL service exposing part of the graph with federation directives
- Supergraph — composed SDL the router understands
- Router — executes one client operation by calling one or more subgraphs
Composition runs in CI when subgraphs publish schemas to a registry; failed composition blocks deploy.
Entities and @key
An entity is a type owned across subgraphs with a @key:
type Product @key(fields: "sku") { sku: ID! name: String!}Another subgraph extends it:
extend type Product @key(fields: "sku") { sku: ID! @external reviews: [Review!]!}The router fetches Product.sku from one subgraph, then references the other subgraph for reviews. Reference resolvers (__resolveReference) load entities by key.
Shareable, external, requires, override
| Directive | Use |
|---|---|
@shareable |
Same field resolved in multiple subgraphs (value must match) |
@external |
Field owned elsewhere; local subgraph uses it for @requires |
@requires |
Fetch extra fields before resolving this field |
@override |
Move field ownership to this subgraph during migration |
Migration teams use @override to shift traffic without renaming client fields.
Tooling landscape
- Apollo Federation v2 — widely deployed; GraphOS registry and Router
- GraphQL Hive — registry, analytics, gateway
- WunderGraph Cosmo — open-source router and composition
- Composite Schemas — GraphQL Foundation–adjacent work on portable composition
Pick tooling that matches your registry, CI, and observability stack—not only brand.
NestJS subgraph sketch
Use ApolloFederationDriver instead of ApolloDriver:
GraphQLModule.forRoot<ApolloFederationDriverConfig>({ driver: ApolloFederationDriver, autoSchemaFile: { federation: 2 },});Define @key on @ObjectType() via @Directive('@key(fields: "id")') patterns supported by @nestjs/graphql federation docs. Each subgraph remains a normal Nest app with its own database.
When to use federation—and when not to
Use when multiple teams ship one consumer-facing graph, subgraph boundaries match domain ownership, and you can invest in composition CI, router ops, and cross-team entity design.
Avoid (for now) when a single team and one deployable suffice, when latency budgets cannot tolerate multi-hop router plans, or when org process cannot enforce entity key agreements. A well-factored monolith GraphQL server plus modular resolvers is often enough until social scale demands federation.
Next: GraphQL glossary.
Check your understanding
Question 1 of 8
0 of 8 checked