Imagine: you have 30 microservices, each with its own API. Clients — web, mobile apps, partners — are forced to make dozens of requests to assemble a single page. Development slows down, and the number of bugs grows. Sound familiar? This is exactly where GraphQL Federation and API Gateway come to the rescue. In this article, we'll break down a real scenario of uniting microservices into a single graph, show the pitfalls, and explain how not to drown in the schema.
The situation: 30 microservices and one tired frontend
A typical picture: an online store has grown, the backend has been split into separate services — catalog, cart, orders, payments, recommendations. Each provides a REST API. To display a product card with recommendations and stock availability, the frontend makes 5–7 requests to different endpoints. The mobile app suffers from delays, and the team spends weeks coordinating contracts.
GraphQL Federation solves this by allowing each microservice to be described as a subgraph with part of the overall schema. Then an API Gateway (e.g., Apollo Router) combines them into a supergraph — a single graph that clients query with one request. The gateway itself decides which subgraphs to call and how to assemble the response.
How it works in practice: step by step
Let's take the same store. Suppose there is a products service and a reviews service. In Apollo Federation, each defines its part of the schema. The products service declares the Product type with fields id, name, price. The reviews service extends this type by adding the reviews field. To link them, the @key directive is used — it indicates that the Product type is identified by the id field. Here's how it looks in the products schema:
type Product @key(fields: "id") {
id: ID!
name: String!
price: Float!
}
And in the reviews schema:
extend type Product @key(fields: "id") {
id: ID! @external
reviews: [Review!]!
}
type Review {
id: ID!
text: String!
rating: Int!
}
Now the client can request a product with reviews in a single query:
query {
product(id: "123") {
name
price
reviews {
text
rating
}
}
}
The gateway (Apollo Router) will parse this query, call the products service for the name and price, and reviews for the reviews, then merge the result. All of this happens automatically, without client involvement.
What's important to know: Apollo Federation v2 (current as of 2026) uses the directives @shareable, @inaccessible, @override to manage shared fields and migrations. For example, @shareable allows multiple subgraphs to return the same field, and @override allows gradually moving a field from one service to another.
Where people most often stumble
-
The N+1 problem. When the gateway requests reviews for a list of products, it may make a separate request to
reviewsfor each product. This kills performance. The solution is DataLoader: batching and caching requests within a subgraph. Without it, federation can become a bottleneck. -
Complex queries without limits. A client can request too deep nesting or a huge number of fields, leading to overload. Be sure to configure query depth limiting and rate limiting at the gateway level.
-
Incorrect entity definition. If
@keyis specified incorrectly or the identifier field is not unique, the gateway won't be able to assemble data correctly. This leads to runtime errors that are hard to catch. -
Lack of monitoring. Without tracing requests through the gateway, you won't see which subgraph is slow. Use Apollo Studio or Grafbase for observability.
Alternatives: GraphQL Mesh and Hasura
Apollo Federation is not the only path. GraphQL Mesh allows you to combine existing REST, gRPC, and other APIs into a single GraphQL gateway without rewriting services. It's a quick start but offers less control over the schema. Hasura provides instant GraphQL over PostgreSQL with ready-made federation but ties you to its ecosystem.
The choice depends on the task: if you already have GraphQL services and need flexible federation — Apollo. If you need to quickly set up a gateway over heterogeneous APIs — Mesh. If data is in PostgreSQL and speed is needed — Hasura.
How to master federation in practice
Self-studying GraphQL Federation hits three barriers: lack of feedback (no one to point out schema errors), scattered information (directives change from version to version), and costly production mistakes. Courses provide structure and case studies but require time and money. Practice on a pet project is free, but without a mentor it's easy to get stuck.
If you want to go from GraphQL basics to building a federated API from multiple microservices with real-world scenarios and feedback, check out the course GraphQL Federation and API Gateway. There you'll build a working supergraph, configure the gateway, and learn to avoid common mistakes. For a deeper dive into this topic, see Yoga and Mobility: Avoiding Common Mistakes in Mindful Movement, Flexibility, and Posture.
Who it's for: backend developers, architects, and team leads familiar with GraphQL or REST who want to move to a federated architecture. If you're just starting your API journey, you should first master basic GraphQL — otherwise federation will seem like magic.