If your microservices still communicate over REST, you don’t need to rewrite them to adopt a unified GraphQL layer. In 2026, GraphQL Federation for microservices has become one of the most effective ways to stitch REST endpoints into one federated graph — not by replacing services, but by composing them. This article walks through a step-by-step pattern for doing exactly that, using subgraphs, entity references, and a supergraph router.
The Shift: From REST Gateway to Federated Graph
Many teams start by placing a GraphQL server in front of their REST APIs. That approach works for simple use cases, but it often becomes a monolithic aggregator that needs to know about every downstream service. Federation flips the model: each microservice owns a small GraphQL subgraph, and a central router composes those subgraphs into a supergraph. The router only builds a query plan; the actual data fetching stays with the service that owns the domain.
For REST-based microservices, this pattern is especially compelling. You do not need to move every service to GraphQL at once. Instead, you can create a subgraph for a REST API, then gradually combine subgraphs as more teams join. The result is a single federated graph that feels like a native GraphQL API to clients, while the backend remains a set of independently deployable REST services.
Step 1: Inventory REST Endpoints and Define Shared Types
Before you write any GraphQL schema, you need an accurate inventory of the REST resources your subgraphs will expose. For each endpoint, document the resource identifier, the response shape, the available query parameters, pagination behavior, and error semantics. This inventory becomes the foundation for your GraphQL types.
Next, define canonical GraphQL types based on those REST responses. Do not blindly mirror every JSON field. REST payloads often contain nested objects, timestamps, and status codes that should be transformed into cleaner GraphQL fields. Choose only the data your clients actually need and map it to a well-named type.
This step is critical because federation relies on types being stable across subgraphs. If two services model the same concept differently, the supergraph will struggle to unify them.
Step 2: Build Subgraphs That Own Their REST Domain
Every subgraph should represent one bounded context. If you have an order service and an inventory service, create two separate subgraphs rather than one combined GraphQL server. Each subgraph is responsible for mapping its own REST calls into GraphQL fields.
This is where you can use a GraphQL server library, but the data loaders remain important. When a subgraph resolves a GraphQL field, it should call the underlying REST endpoint with an efficient batch strategy. For example, if a query asks for many orders, the subgraph should use a data loader to combine requests or at least avoid making one REST call per field.
Keep the subgraph thin. It should contain only schema and resolvers, not business logic. The business logic stays in the REST service. The subgraph acts as a translation layer between a stable GraphQL contract and the REST resource.
Step 3: Compose Entities Across Subgraphs with Reference Resolvers
Federation’s real power appears when you need to combine data from multiple REST services in a single query. Suppose the order service returns an order, and the inventory service returns stock status. In a federated graph, you can make those two types reference each other using the @key directive and a reference resolver.
The order subgraph can define an Order type with a field that returns inventory information, but it does not know how to fetch that inventory. Instead, the inventory subgraph extends the Order type and provides a resolver for the Inventory field. The router sees that field and calls the inventory subgraph with the order’s ID.
This pattern is the step-by-step stitch you need. It means the REST endpoints stay separated, but the federated graph can join data from both without a custom aggregation service.
type Query {
order(id: ID!): Order
}
type Order @key(fields: "id") {
id: ID!
total: Float
status: String
inventory: Inventory
}
In the inventory subgraph, you would then extend the Order type with a reference resolver that fetches stock levels from the inventory REST API. From the client’s perspective, the order and its inventory status are one graph.
Step 4: Publish Subgraphs and Let the Router Build the Supergraph
Once your subgraphs are ready, the next step is to publish their SDL to a schema registry. The registry enables your federation router to fetch all subgraph schemas and build a supergraph. The router uses the @key directives and entity references to understand how types relate across subgraphs.
During this step, you should version your subgraphs independently. Teams can continue to make REST changes internally, as long as the subgraph contract remains backward compatible. When a subgraph is published, the router can update the query plan without requiring a coordinated deployment across every service.
This is a major advantage over the older REST aggregator pattern. You do not need a central GraphQL team to know every detail of every REST API. Each team maintains its own subgraph, which keeps ownership aligned with the underlying microservice.
Step 5: Use Query Plan Analysis to Tune REST Performance
Federation does not magically solve performance problems. The router creates a query plan, but the REST calls still need to be efficient. Analyze the query plan for the most common client queries. Look for places where the router must sequentially call multiple subgraphs, or where a subgraph makes multiple REST calls to satisfy a single field.
Common optimizations include adding caching to subgraph responses, using data loaders to batch REST requests, and setting reasonable timeouts on each downstream call. You can also use calculated fields or denormalized data in a subgraph to avoid an expensive REST round trip. Because the subgraph is the only place that calls the REST endpoint, you can tune it without affecting any other service.
The goal is to keep the federated graph fast enough that clients prefer it over direct REST calls. If a query plan requires too many round trips, consider redesigning the types or adding a lightweight REST aggregation endpoint inside one subgraph to reduce the number of caller requests.
Practical Example: Order and Inventory Services
Imagine you have two REST services. The order service exposes GET /orders/{id} and the inventory service exposes GET /inventory/status?orderId={id}. Without federation, a client might need two API calls and then join the results manually. With Federation, the order subgraph fetches order details, while the inventory subgraph resolves the inventory status.
The query plan will look roughly like this: the router sends the query to the order subgraph, receives the order ID and base fields, then sends a second query to the inventory subgraph to resolve the inventory field. The client makes one request to the supergraph and receives the complete result.
This pattern is especially useful in microservices landscapes where new services are added frequently. When a new team exposes a REST API, they can publish a subgraph and immediately become part of the federated graph. The rest of the organization can query their data without needing a central contract review.
Avoiding Common Pitfalls in REST-to-Federation Stitching
The most common mistake is trying to expose every REST endpoint in a subgraph before aligning types. That leads to a messy supergraph with duplicate or conflicting type names. Instead, define a narrow set of canonical types first and add fields only when there is a real query pattern.
Another pitfall is forgetting that federation does not remove the need for REST API best practices. Subgraphs can hide awkward REST interactions, but they cannot fix a chatty API. If a subgraph needs to make ten REST calls to resolve one field, clients will still experience latency even though the query looks simple.
Finally, do not treat the subgraph as a full replacement for a REST consumer. Some client applications are better off calling REST directly. Use federation where graph-like queries and cross-service joins add value; leave the rest untouched.
Conclusion
GraphQL Federation for microservices offers a clear path for stitching REST endpoints into one federated graph without forcing every team to migrate to new technology. By inventorying REST resources, building focused subgraphs, using entity references, and letting a router compose the final supergraph, you can unify your data layer in a way that respects service boundaries. This pattern turns federation from a GraphQL-native advantage into a practical integration strategy for REST-first organizations.
