Docs
Launch GraphOS Studio

Migrating from schema stitching

How to move your services to Apollo Federation


If you have a distributed that uses schema stitching, follow the steps in this guide to migrate it to use .

For a real-world example of an organization benefiting from this migration, see this blog post.

Summary of steps

This guide describes a set of steps for migrating architecture incrementally from stitching to federation. In order to do so, we rely on the fact that changes necessary for federation are completely backwards compatible. In other words, services that implement a part of your (subgraphs) can be used in both your stitching gateway and your Apollo gateway.

We recommend that you begin by modifying existing s in place to support the federation specification while continuing to support schema stitching as well. At this point, you can stand up an Apollo gateway side-by-side with your existing stitching gateway and migrate over the links between the s in an incremental, backward compatible way.

Here are the high-level steps for migrating to :

  1. Add federation support to your s.
  2. Register your s with a registry.
  3. Start up an instance of as a gateway.
  4. Migrate stitching logic from your schema-stitching gateway to your s.
  5. Move traffic from the schema-stitching gateway to the gateway.
  6. Remove schema-stitching s from your federated schema and complete your migration.

Each step is described in detail below.

This GitHub repository shows the same project before and after migrating to from schema stitching.

Step 1: Add federation support to your subgraphs

You can add federation support to your s without impacting your existing schema-stitching architecture. Support for federation is fully compatible with schema stitching.

Because of this, we recommend that you migrate your s in-place instead of creating replacement subgraphs. Doing so helps you identify any type conflicts that exist across your graph.

Using Apollo Server

If your s use , add federation support to them by installing the @apollo/subgraph package:

npm install @apollo/subgraph

Then use the buildSubgraphSchema function to augment your schema with s that are necessary for federation support:

const { ApolloServer } = require('@apollo/server');
const { buildSubgraphSchema } = require('@apollo/subgraph');
const server = new ApolloServer({
schema: buildSubgraphSchema([
{
typeDefs,
resolvers,
},
]),
});

Using a GraphQL server besides Apollo Server

There are several community-contributed packages that add federation support to other runtimes.

Step 2: Register your schemas with a GraphQL registry

We strongly recommend that you register all of your s with an external registry. This registry supports running the gateway with the s' partial schemas. Additionally, it enables tracking changes at the subgraph level and protecting the graph from changes that break .

Apollo Studio provides a free schema registry that helps you manage your federated gateway's configuration. You provide your gateway a Studio API key on startup, which directs the gateway to download your schemas automatically in a fault-tolerant way.

Studio can also provide schema validation to ensure that all changes you make to your s are compatible with your complete graph.

Step 3: Start up an Apollo Server gateway

After you've registered your schemas, you can start exposing your s from a federation-compatible gateway. 's gateway is a planner and executor that handles incoming requests and breaks them down into a collection of s to perform on your subgraphs.

We recommend setting up the gateway alongside your existing schema-stitching gateway. Depending on your infrastructure, you might even want to run both in the same process to support dynamically routing traffic through one gateway or the other.

To enable managed configuration with Apollo Studio, set the APOLLO_KEY and APOLLO_GRAPH_REF environment variables when you start up your gateway, and do not provide the supergraphSDL or serviceList constructor option to ApolloGateway. For details, see the Apollo Studio documentation.

After your gateway is set up, you can make direct queries to it that are routed to the correct s.

Step 4: Move linking logic to your subgraphs

When using a schema-stitching gateway, your linking logic typically resides in the gateway itself. In the federation model, however, linking logic resides in each subgraph. Therefore, you need to migrate linking logic from your schema-stitching gateway into each of your s.

Here are recommendations for common cases when migrating your logic:

  • Fragments: s in a schema-stitching , usually translate to a combination of @key and @requires s in a federated model. In general, think of @key as the (s) that completely identify an entity, and only use @requires for additional, non-identifying information.
  • Filtering types: We do not recommend filtering types out of your exposed schema when using a gateway. If you want to hide types, do not include them in your 's registered schema.
  • Renaming types: If you are currently renaming types at the gateway level, rename these types at the level instead.
  • Transforming fields: If you are currently transforming s at the gateway level, transform these fields at the level instead.

Adding resolvers to your subgraphs

At this point your s support federation, but they still need to be able to resolve to types that are defined in other s.

A schema-stitching architecture declares this logic at the gateway level using the delegateToSchema function, like so:

resolvers: {
Reservation: {
user: {
fragment: `... on Reservation { userId }`,
resolve: (parent, args, context, info) => {
return info.mergeInfo.delegateToSchema({
schema: userSchema,
operation: 'query',
fieldName: 'user',
args: {
id: parent.userId,
},
context,
info,
});
},
},
},
}

This calls Query.user on the userSchema to look up a User. It adds that user to the Reservation.user that was previously defined at the gateway. This code can all remain. You don't need to remove it from the stitched gateway. In fact, if you did that, the stitched gateway would break.

On the other hand, a federated architecture defines its s at the level. These resolvers rely on entities, which are identified by a unique key. For example, the Reservation must define the Reservation type as an entity to allow other s to extend it. These other subgraphs use the Reservation's @key s to uniquely identify a given instance:

type Reservation @key(fields: "id") {
id: ID!
...
}

In the Users , you can then extend the Reservation type with a user like so:

extend type Reservation @key(fields: "id") {
id: ID! @external
userId: ID! @external
user: User @requires(fields: "userId")
}

The user indicates that it @requires a Reservation's userId in order to identify the user that made the reservation.

Then in the Users , you can add a for Reservation.user like so:

{
Reservation: {
user: ({ userId }) => {
return lookupUser(userId);
},
}
}

Federated s like this one always receive an object that represents an instance of the extended entity. This object includes the s that are part of the entity's @key, along with any other s that the @requires.

For example, this Reservation.user receives the id of the reservation and a userId. You can use the userId to look up the corresponding user.

Step 5: Move traffic from the schema-stitching gateway to the Apollo Server gateway

At this point, both your schema-stitching gateway and your federated gateway are able to resolve s. You can now begin moving traffic from the schema-stitching gateway to the federated gateway.

Perform this migration in the manner that best suits your infrastructure and applications.

Some options include:

  • Testing a complete migration in your staging environment to verify that both gateways behave identically
  • Use HTTP headers or feature flags to migrate your internal clients without affecting your user-facing clients

Step 6: Remove schema-stitching fields from your federated schema

After you've fully migrated your and incoming traffic to use your federated gateway, you can remove all stitching-specific logic from your architecture.

You can now begin to modify your existing schema to take full advantage of the features that federation provides. These features include:

Previous
Entity interfaces
Next
Overview
Edit on GitHubEditForumsDiscord