3. Monolith as a subgraph


In this lesson, we're going to tackle the first step for migrating our monolith app into a . We'll start by converting the monolith server into a single , which will run on a different port. Along the way, we'll also:

  • Review how to create a using
  • Publish our first to the Apollo registry
Diagram of the migration plan step 1. Step 1 was to create a single large subgraph with the exact same schema as the monolith, and run it on a different port. This single subgraph will be published to the registry.

Service check

Let's make sure all of our processes are still running from the previous lesson.

  • One terminal should be running npm start, to start the monolith server on port 4000.
  • Another terminal should be running npm run launch, to start our services in the monolith directory on ports 4010 and 4011.

✏️ Importing packages

  1. Let's stop the main monolith server process with CTRL+C.

  2. Then, install the @apollo/subgraph package.

    npm install @apollo/subgraph

    This directory contains an index.js file, which is running our monolith server. Let's adjust it slightly to turn it into a monolith subgraph server instead.

  3. To make this server a , we'll need to import the buildSubgraphSchema method from the @apollo/subgraph package. Add the following line to the imports in your index.js file:

    const { buildSubgraphSchema } = require("@apollo/subgraph");

✏️ Updating the monolith server

Next, let's modify our ApolloServer instance. Right now, we pass our typeDefs and resolvers directly to the ApolloServer constructor.

const server = new ApolloServer({

To convert this server into a , let's define a schema property in the constructor instead. We'll use the buildSubgraphSchema method, as we did in the first course, passing it an object that contains the typeDefs and resolvers.

const server = new ApolloServer({
schema: buildSubgraphSchema({

While we're here, let's also set our server to listen on port 4001 (a different port from where it was originally running!). We want the monolith to use a different port because, as we outlined in our migration plan, we'll set up the to take over port 4000. This way, the client doesn't need to make any changes to communicate with the .

Set up the server's listen function to run on port 4001.

- const port = 4000;
+ const port = 4001;

✏️ Federation 2 subgraph schema definition

We'll want to make sure to opt in to the latest Federation 2 features for this . Open up the schema.graphql file in the same monolith directory and add the following snippet at the top:

extend schema
@link(url: "https://specs.apollo.dev/federation/v2.5",
import: ["@key"])

With this line, we can specify the various we'd like to use within our schema file (such as @key, as shown in the import).

With that, we're ready to restart our monolith server process!

npm start

We'll see some output in our console and then the message "🚀 Monolith subgraph running at http://localhost:4001/".

Testing the monolith subgraph

Let's visit that URL http://localhost:4001 in the browser to open up again. Let's try out the same from the previous lesson to make sure everything is still working as before!

query GetAllAmenities {
listingAmenities {

After running the , we can see data showing up in the Response panel on the right. Great, we know it's working! By transforming the monolith schema into a , we know that all of our schema's types, , and features are still preserved and intact.

We've got our first ready, so the next step is to publish it to the registry!

Publishing our subgraph

We want to publish our , but to where? Well, we already have a graph in Studio, the one we set up in the previous lesson.

Recall that the rover subgraph publish command looks like this:

rover subgraph publish <APOLLO_GRAPH_REF> \
--schema <SCHEMA_FILE_PATH> \
--name <SUBGRAPH_NAME> \
--routing-url <SERVER_URL>

Let's publish this !

Tip: We're going to be using a few different commands as we go through the course. You can create a new file to store these commands and copy-paste them to the terminal when you need them, or you can incorporate them into scripts to run in the package.json file.

Open up a new terminal window in the root directory and run the command below, substituting the values of the APOLLO_GRAPH_REF flag to match your own. We're going to name this monolith.

rover subgraph publish <APOLLO_GRAPH_REF> \
--schema ./monolith/schema.graphql \
--name monolith \
--routing-url http://localhost:4001

Uh-oh... when we run the command, we'll see that we get an error back in the terminal! (You'll see the value of your own APOLLO_GRAPH_REF in place of the flag below.)

error[E007]: The graph `[APOLLO_GRAPH_REF]` is a non-federated graph.
This operation is only possible for federated graphs.

But what went wrong?

Well, when we set up our in Studio, we chose a monolith architecture, which created a non-federated . This was suitable for our purposes at the time, but now that we're breaking down the monolith into , we need to make sure our graph is using federation.

We can convert it into a using the same command as before: rover subgraph publish, and the addition of the --convert flag.

Let's try that command again, this time including the --convert flag.

rover subgraph publish <APOLLO_GRAPH_REF> \
--schema ./monolith/schema.graphql \
--name monolith \
--routing-url http://localhost:4001 \

The addition of the --convert flag at the end will tell Studio to convert the existing into a . And now we should see that the command ran successfully, and our was published!

Illustration of the monolith being turned into a subgraph as the first step of our migration plan.

Reviewing our changes in Studio

In the browser, let's get back to the we created in Apollo Studio. We'll see that the graph now has a label indicating that it's federated.

We can also navigate to the Schema page's SDL tab. Under the Subgraphs section, we can see the first that we called monolith.

Screenshot of Apollo Studio Schema page SDL tab. It shows the graph as Federated with v2 and the monolith subgraph has been added.


Which of these does the migration plan enable us to do when converting the monolith into a supergraph?

Key takeaways

  • We set up the monolith to use port 4001 because, as we outlined in our migration plan, we want the to take over port 4000. (Don't worry - we haven't gotten there yet!) This way, the client doesn't need to make any changes to communicate with the .
  • To convert an existing in Studio into a , we use the same rover subgraph publish command to publish a schema, and add a --convert flag.

Up next

Let's review our migration plan. We can successfully check off the first step, so let's see what's up next:

  1. Convert the monolith GraphQL server into a subgraph server, which we'll run on a different port. This subgraph will be published to the schema registry.
Diagram of the migration plan step 1. Step 1 was to create a single large subgraph with the exact same schema as the monolith, and run it on a different port. This single subgraph will be published to the registry.
  1. ➡️ Create a router running on the monolith's original port. The router will be connected to the schema registry and will handle all of the same queries that were previously being sent to the monolith server.

  2. Start to split off small chunks of our single monolith into new domain-specific subgraphs. This will take several steps, which we'll explain in more detail later on.

The next step is to create a . This router needs to handle authentication and authorization in Airlock, so let's learn about how that works in the next lesson.


Share your questions and comments about this lesson

Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.