Implementing Apollo Federation: From Subgraphs to a Unified GraphQL Supergraph
Learn how to compose multiple GraphQL services with Apollo Federation, define shared entities, validate schemas, and deploy a gateway that stitches a supergraph for modular, team‑agnostic development.
29 Jul 2026, 17:23 UTC

Why Use Apollo Federation
When multiple teams own independent GraphQL services, clients often need data that spans those services. Exposing a single endpoint that stitches together the services keeps the public API stable while letting teams evolve their internal APIs. Apollo Federation gives you a declarative way to declare shared entity types and cross‑service relationships, letting the gateway orchestrate the composition for you.
Prerequisites
- Node.js 18+ and npm or yarn
- Three packages installed globally or as dev dependencies:
apollo-server,apollo-gateway, and@apollo/federation - Two or more subgraph services that expose a GraphQL schema via introspection (e.g., a User service and an Order service)
- Access to Apollo Studio (optional but recommended for monitoring and schema diffs)
Step 1: Define Entity Types with @key
Each subgraph declares the entity types it owns. The @key directive tells the gateway how to uniquely identify an entity across the system.
# user-service/schema.graphql
type User @key(fields: "id") {
id: ID!
name: String!
email: String!
}
# order-service/schema.graphql
type Order @key(fields: "id") {
id: ID!
total: Float!
userId: ID!
}
Step 2: Extend with @provides and @requires
When a service needs to expose a field that comes from another service, it uses @provides (to add data) or @requires (to declare a dependency).
# order-service/schema.graphql
extend type User @key(fields: "id") {
orders: [Order!]! @provides(fields: "id total")
}
In this example, the Order service tells the gateway that it can supply the orders field for User by providing the id and total of each order. The gateway will automatically fetch those values from the Order service when a client queries orders on a user.
Step 3: Compose the Supergraph
Run the compose command locally to fetch each subgraph’s SDL via introspection and build a single supergraph SDL. This step validates type consistency and reports conflicts before deployment.
npx apollo gateway:compose \
--subgraphs user.graphql,order.graphql \
--output supergraph.graphql
Expected result: a file supergraph.graphql containing the merged schema. If there are validation errors, the command will list them; you’ll need to adjust the subgraphs until the compose succeeds.
Step 4: Deploy the Gateway
Start the gateway pointing at the composed supergraph. The gateway will load the SDL, set up resolvers that delegate to the appropriate subgraphs, and expose a single GraphQL endpoint.
npx apollo gateway:start \
--supergraph supergraph.graphql \
--port 4000
Permissions: Run as a user that can bind to the chosen port. The gateway will log each resolver invocation; enable tracing with APOLLO_GW_TRACE=true to see which subgraph handles each field.
Step 5: Verify and Query
Send a federated query that touches multiple services:
query {
user(id: "1") {
id
name
orders {
id
total
}
}
}
Expected response:
{
"data": {
"user": {
"id": "1",
"name": "Alice",
"orders": [
{ "id": "o1", "total": 99.99 },
{ "id": "o2", "total": 49.50 }
]
}
}
}
Verify that the gateway logs show one resolver call per entity per subgraph. Use Apollo Studio’s schema diff tool to compare the composed supergraph against a baseline and catch unexpected changes.
Common Pitfalls and Recovery
- Schema Mismatches: If two subgraphs declare the same type with different fields, the compose step will fail. Resolve by aligning the type definitions or using
@externalto indicate fields owned by another service. - Circular Dependencies: Entities that depend on each other can create resolution loops. Design your graph to avoid cycles or limit
@requiresusage to non‑recursive fields. - Large Supergraphs: A supergraph with many entities can slow gateway startup. Consider versioning subgraphs or using incremental schema stitching if startup time becomes a bottleneck.
- Runtime Errors: If a subgraph is down, the gateway will return
nullfor the affected fields. Ensure each subgraph has health checks and that the gateway is configured with appropriate retry logic.
Conclusion
Apollo Federation lets you build a modular GraphQL architecture where each team owns a subgraph, yet clients can query a single unified API. By declaring entities with @key, extending types with @provides or @requires, and validating the supergraph locally before deployment, you can avoid runtime conflicts and maintain a clear contract between services.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.