3. From mono, to sub, to supergraph

🙌 Hands-on time!

Time to upgrade our Catstronauts app with the . Let's start with a freshly cloned project. First, create a new directory called supergraph, then run the following command:

git clone https://github.com/apollographql-education/lift-off-supergraph-demo-tracks.git

The project starts where we left it in Lift-off IV, with a few differences:

  1. The schema is now defined in a standalone .graphql file, which also changes how it's loaded into our server.
  2. The server itself is now running on 4!
  3. We're importing the gql tag directly from the graphql-tag package.

Let's navigate to the projects folder we've just cloned and install its dependencies.

cd lift-off-supergraph-demo-tracks && npm install

Then it with:

npm run dev

This should start our and make it available on port 4001. We can then navigate to Sandbox at http://localhost:4001, where we can our locally running .

Note: npm run dev uses nodemon to watch any changes to our app or schema and restart the automatically when needed.

In Sandbox, we see three available of the Query type: tracksForHome, track, and modules, as well as one Mutation : incrementTrackViews. Let's try out a to retrieve the title for each of our tracks.

query TracksForHome {
tracksForHome {
tracksforhome query results

Great, it all works as expected 😎.

To convert this into a , we'll first need to install a new package, @apollo/subgraph.

npm install @apollo/subgraph

Then we'll navigate to schema.graphql and add a line at the top of the file to make it ready for Federation 2. (This lets us use the latest and greatest features in our .)

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

Finally, back in index.js, we'll import the buildSubgraphSchema function from the package we've just installed.

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

The buildSubgraphSchema function does exactly what its name suggests: it creates a that can be composed as part of a larger . We'll use this function in the server constructor, passing it our type definitions and their corresponding functions.

const server = new ApolloServer({
schema: buildSubgraphSchema({ typeDefs, resolvers }),

Our schema definition is now boosted with federation support! 🚀

Here's the diff between the Lift-off IV starting point and the current state of our project:

Locally, we have now effectively turned our monograph into a subgraph. 🥳

Let's check that everything still works the same as before. Our server automatically restarted as we made changes to it, so we can rerun the same in Sandbox and confirm that we get back the same results. The only noticeable difference is that we can see a new _service on the Query type in the Documentation sidebar. We won't need to use this directly (it exists as part of our schema as a requirement for to comply with the federation specs), but it lets us know we're now working with a subgraph.

The schema for this holds all of our tracks information, so we can call this our tracks .

rover dev tracks subgraph

Goal #1 complete, go on and check the task below 🎉!


With this first working , we're one step closer to our objectives. We now need to create a from this first subgraph and set up an endpoint where clients can our supergraph. To do that, we'll need the .

Rover CLI

is Apollo's command line interface (CLI) tool that helps developers work with . It's a handy and versatile tool that can be used for both local development and CI/CD. We can use it to run checks, publish schemas to the Apollo registry, and much more (that we'll discover in the Voyage series).

For now, let's see how it can help us speed up local development for our and .

First, let's install the binary on our machine. In a terminal window, paste the following command:

curl -sSL https://rover.apollo.dev/nix/latest | sh

Note: If you want to install using a different method, see the official Rover installation docs.


When the installation is complete, we can run rover --help to see the many commands this tool provides.

rover help

We'll only need one for this course: rover dev. The rover dev command enables us to run our locally with a and one or more .

Important note: The rover dev command is intended exclusively for local development, and we should never use it in production as it is not optimized for this use case.

Local development flow

The local development flow is straightforward:

  • Start your if it isn't already running.
  • Open a new terminal window and navigate to the 's directory.
  • Run rover dev

When we have multiple , we'll repeat these steps for each new subgraph we want to add to our .

Under the hood, the first rover dev process we run will automatically start an instance of the . It then listens for any additional rover dev processes, which each indicate there's another to add to the . Each time a subgraph is added, the original rover dev process composes an updated .

Let's try out this rover dev workflow with our first , tracks, which is already running on port 4001.

rover dev

In another terminal window, run rover dev from the lift-off-supergraph-demo-tracks directory.

prompts us to provide the 's URL, which is http://localhost:4001. For the name, we'll add tracks.

Because this is the first rover dev process we've started, composes the , spins up the , and prints out a few lines indicating the URL where the supergraph can be queried: http://localhost:3000. Let's head over there and for some tracks.

Open a new browser window and navigate to Sandbox at http://localhost:3000. Then run the following :

query TracksForHome {
tracksForHome {

Excellent, we have a working ! For now, though, it has only one . Time to add another one!


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.