Overview
In this lesson, we're going to tackle the first step for migrating our monolith app into a supergraph. We'll start by converting the monolith server into a single subgraph, which will run on a different port. Along the way, we'll also:
- Review how to create a subgraph using Apollo Server
- Publish our first subgraph to the Apollo 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
Let's stop the main monolith server process with
CTRL+C
.Then, install the
@apollo/subgraph
package.monolithnpm install @apollo/subgraphThis 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.To make this server a subgraph, we'll need to import the
buildSubgraphSchema
method from the@apollo/subgraph
package. Add the following line to the imports in yourindex.js
file:monolith/index.jsconst { 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({typeDefs,resolvers,});
To convert this server into a subgraph, 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({typeDefs,resolvers,}),});
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
subgraph to use a different port because, as we outlined in our migration plan, we'll set up the router to take over port 4000
. This way, the client doesn't need to make any changes to communicate with the GraphQL server.
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 our Federation 2 features for this subgraph. 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.0",import: ["@key"])
With this line, we can specify the various directives 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 Apollo Sandbox again. Let's try out the same query from the previous lesson to make sure everything is still working as before!
query GetAllAmenities {listingAmenities {categoryname}}
After running the query, 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 subgraph, we know that all of our schema's types, fields, and features are still preserved and intact.
We've got our first subgraph ready, so the next step is to publish it to the registry!
Publishing our subgraph
We want to publish our subgraph, 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 subgraph!
Tip: We're going to be using a few different Rover 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 subgraph 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
variable 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 graph in Studio, we chose a monolith architecture, which created a non-federated graph. This was suitable for our purposes at the time, but now that we're breaking down the monolith into subgraphs, we need to make sure our graph is using federation.
We can convert it into a supergraph 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 \--convert
The addition of the --convert
flag at the end will tell Studio to convert the existing graph into a supergraph. And now we should see that the command ran successfully, and our subgraph was published!

Reviewing our changes in Studio
In the browser, let's get back to the graph 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 subgraph that we called monolith
.

Practice
Key takeaways
- We set up the monolith subgraph to use port
4001
because, as we outlined in our migration plan, we want the router to take over port4000
. (Don't worry - we haven't gotten there yet!) This way, the client doesn't need to make any changes to communicate with the router. - To convert an existing graph in Studio into a supergraph, 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:
- ✅ 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.
➡️ 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.
Start to split off small chunks of our single monolith subgraph 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 router. 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.