Build a Federated GraphQL Supergraph with Apollo Router 1.x
Set up an Apollo Router 1.x instance that stitches together two subgraphs—accounts and orders—into a single GraphQL endpoint. Follow a step‑by‑step guide covering schema design, local composition, router configuration, runtime checks, and recovery strategies.
05 Aug 2025, 03:56 UTC

Desired Outcome
Launch an Apollo Router that stitches together two independent subgraphs—accounts and orders—into a single GraphQL endpoint. The router should resolve entities across subgraphs, expose a healthy health‑check, and support local hot‑reloading for rapid iteration.
Prerequisites
- Node.js 18+ or Go 1.21+ installed.
- Each subgraph runs on its own HTTP server (e.g., Fastify, Express, or a Go HTTP server).
- Dependencies:
@apollo/subgraphv2.x in each subgraph.roverCLI v1.x (install vianpm i -g @apollo/rover).- Apollo Router binary v1.x (download from Apollo docs).
- Optional: Apollo Studio account for managed federation.
Subgraph Design
Define each subgraph’s SDL with @key directives for entities and @external where needed. Example schemas:
// accounts/schema.graphql
type User @key(fields: "id") {
id: ID!
name: String!
email: String!
orders: [Order] @external
}
type Query {
user(id: ID!): User
}
// orders/schema.graphql
type Order @key(fields: "id") {
id: ID!
total: Float!
user: User @external
}
type User @key(fields: "id") {
id: ID!
orders: [Order]
}
type Query {
order(id: ID!): Order
}
Implement __resolveReference resolvers for each entity in the corresponding subgraph.
Local Composition
Create a supergraph.yaml that lists the running subgraphs:
subgraphs:
accounts:
routing_url: http://localhost:4001/graphql
orders:
routing_url: http://localhost:4002/graphql
Run composition to generate the supergraph SDL and validate schema consistency:
rover supergraph compose \
--config ./supergraph.yaml \
--output ./supergraph.graphql
Verify the command exits with code 0 and that rover reports no ERROR diagnostics.
Router Configuration
Define router.yaml to control telemetry, CORS, and health‑check behavior:
router:
supergraph: ./supergraph.graphql
telemetry:
enabled: true
cors:
allow_origins: "*"
allow_methods: GET, POST
health:
path: /health
timeout_seconds: 10
subgraphs:
accounts:
url: http://localhost:4001/graphql
orders:
url: http://localhost:4002/graphql
Running the Router
./router \
--config ./router.yaml \
--dev
Run with --dev to enable hot‑reloading of the supergraph when supergraph.graphql changes. Observe logs that indicate "Router ready" and each subgraph’s health status.
Validation
Once the router is up, perform the following checks:
- Introspection: Query
__schemato ensure all types from both subgraphs are present.curl -X POST http://localhost:8080/graphql \ -H "Content-Type: application/json" \ -d '{"query":"{ __schema { types { name } } }"}' - Cross‑subgraph query: Retrieve a user and their orders.
curl -X POST http://localhost:8080/graphql \ -H "Content-Type: application/json" \ -d '{"query":"{ user(id: \"1\") { id name orders { id total } } }"}' - Check the metrics endpoint
/metricsforrouter_graphql_errors_totalandsubgraph_request_duration_secondsto confirm no errors.
Recovery Options
If composition fails, run Rover with JSON diagnostics to pinpoint the issue:
rover supergraph compose \
--config ./supergraph.yaml \
--output ./supergraph.graphql \
--output-format json > diagnostics.json
Inspect diagnostics.json for missing @key directives or mismatched field names. Fix the SDL and re‑compose.
On router startup failure, validate the supergraph SDL syntax:
rover supergraph validate \
--supergraph ./supergraph.graphql
If the router stops serving healthy subgraphs, verify each subgraph’s health‑check endpoint returns 200 OK within the configured timeout.
Local Development Workflow
Use rover dev to hot‑reload composition while subgraphs run locally:
rover dev \
--config ./supergraph.yaml \
--dev-mode
This starts a lightweight router that watches supergraph.graphql for changes, eliminating the need to restart the binary manually.
CI/CD Integration
In pull‑request pipelines, prevent breaking changes with:
rover supergraph check \
--graph=my-graph@variant \
--schema=./supergraph.graphql
Deploy the supergraph to Apollo Studio on merge if using managed federation:
rover supergraph push \
--graph=my-graph@production \
--schema=./supergraph.graphql
Limitations & Notes
- Only
@apollo/subgraphv2.x is supported; older@apollo/federationpackages will break composition. - Apollo Router v1.x uses
router.yaml; mixing it with the Gateway library is unsupported. - Entity
@keyfields must match exactly across all subgraphs that extend the entity. - Subgraph health checks must respond within the router’s timeout; otherwise the router will exclude the subgraph.
- Managed federation requires an Enterprise Apollo Studio plan for production variants; the free tier only supports a development variant.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.