3. Monolith as a subgraph7m

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
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.

    monolith
    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 subgraph, 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:

    monolith/index.js
    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.

monolith/index.js
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.

monolith/index.js
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.

monolith/index.js
- 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:

monolith/schema.graphql
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!

monolith
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 {
category
name
}
}

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!

Task!
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 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.

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

Practice

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 subgraph to use port 4001 because, as we outlined in our migration plan, we want the router 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 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:

  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 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.

Previous
Next