6. Adding a subgraph
5m

Overview

Let's give our something to sing about—literally! We're going to pair our soundtracks data with meals that need some music! With , it's straightforward: we're only a couple clicks away!

In this lesson, we will:

  • Add a new to our using Studio
  • Inspect an 's

Introducing recipes

Everyone needs a good soundtrack to go with the special dish they're whipping up! To that end, we're about to get to know the recipes API; it's another full-fledged with a schema, , and .

We can use Sandbox to explore it. Here's the endpoint:

Recipes API
https://poetic-recipes-api-2f18189a9776.herokuapp.com
https://studio.apollographql.com/sandbox

Sandbox - recipes API

Right now, the API is simply a small collection of recipes. We can ask for things like:

  • a random recipe
  • the full list of recipes in its database
  • the most recently added recipes
  • a particular recipe's ingredients, cooking time, instructions, and more

The coolest part? It's not a .NET server. Instead, it's written in JavaScript and uses Apollo Server! Remember, this isn't a problem for our . Each we bring on board can be written using a different language or framework. We're about to see this in action!

Let's welcome this and its brand new functionality into our API—we can do this without cloning the repository or making any adjustments at all.

Adding a subgraph

  1. Head over to your 's page in Studio and navigate to the Subgraphs page. We can see that our soundtracks is already here, pointing to where we hosted it.

  2. Click Add a subgraph.

    https://studio.apollographql.com/

    Studio - Add subgraph button

    Note: You can also add a using the , like what we did for the soundtracks ! To find the instructions, click the arrow next to Add subgraph and select Add subgraph using the Rover CLI.

  3. We'll need to provide two things about the : its URL and its name.

    Routing URL
    https://poetic-recipes-api-2f18189a9776.herokuapp.com/
    Subgraph name
    recipes
    https://studio.apollographql.com/

    Studio - Add subgraph modal

  4. Then, click Add subgraph. It takes a few moments for to check that the successfully composes with all other existing subgraphs and produces a (all necessary steps for the process). And that's it!

    https://studio.apollographql.com/

    Studio - Add subgraph success

Our new supergraph schema

Let's check out the Changelog through the navigation menu.

https://studio.apollographql.com/

Changelog page in Studio

We can see our has grown—with types and all about recipes! We've got Ingredient, Recipe, and several new added to our Query type like allRecipes and recentlyAddedRecipes.

All of these new types and are presumably all coming from the recipes . We can confirm which are coming from which subgraph by heading over to the Schema page.

Under the Reference tab, with Query selected, we can see the entry points to our . The Subgraph column indicates the each is coming from!

https://studio.apollographql.com/

Schema reference page for the Query type in Studio

We've got four new available from our Query entry point: allRecipes, randomRecipe, recentlyAddedRecipes, and a specific recipe(id).

Our has officially grown!

Sending a query

With both soundtracks and recipes data under our fingertips, are you itching to put the power of our to the test? Let's try sending a that involves both .

Let's jump back to the Query tab in the Schema page, where we could see all our available entry points to the . Under the Actions column of the Schema page, click the Play icon right next to the recipe .

https://studio.apollographql.com/

Schema reference page in Studio, click the play icon next to the cookware field

This will open up Explorer with the Documentation tab showing the and what we can use to build our .

https://studio.apollographql.com/

Explorer, with the recipe field open in the Documentation field

If you have an currently in the Operation panel, clear it or open up a new Explorer tab. We want to start fresh here!

Under recipe we can see its description—Returns a specific recipe based on its ID—along with the for a Recipe type. Let's add the name, cookingTime, description and instructions.

query Recipe($recipeId: ID!) {
recipe(id: $recipeId) {
name
cookingTime
description
instructions
}
}

Because this returns data for a specific recipe, we need to give it an ID as an . Here's what we can paste into the Variables panel.

Variables
{
"recipeId": "recgUKbxnQssl9fYc"
}

That's data from the recipes ! Let's bring data from the soundtracks into the mix! Why don't we pull in data for featured playlists?

There's a handy shortcut in Explorer to search our schema for that . Hit Command + K or Ctrl + K to access the spotlight search. Start typing featuredPlaylists and the Query.featuredPlaylists should pop up.

https://studio.apollographql.com/

Explorer using Spotlight to search for a specific field

We'll select that and now we can access it directly in the Documentation panel. Saves us a couple clicks, and it'll be especially helpful as our continues to grow!

Let's add the featuredPlaylists and ask for the name of each playlist as the sub.

Lastly, we'll rename the to be more explicit. Give it the name GetRecipeAndPlaylists.

Your should now look like this:

query GetRecipeAndPlaylists($recipeId: ID!) {
recipe(id: $recipeId) {
name
cookingTime
description
instructions
}
featuredPlaylists {
name
}
}

Let's run it!

https://studio.apollographql.com/

Query returning data

Woohoo, and we get data back! One query, but with data coming from two separate subgraphs 🤯🎉

The query plan

We can validate where exactly the data for each is coming from by inspecting the query plan. The is like a blueprint for an : the set of instructions that the uses to send smaller operations to the responsible for those particular .

Click on the arrow beside Response and select "Query Plan Preview".

Query plan preview

We can view this as a chart, or as text if we select the icon to "Show plan as text".

Query plan preview

Query plan preview
QueryPlan {
Parallel {
Fetch(service: "recipes") {
{
recipe(id: $recipeId) {
name
cookingTime
description
instructions
}
}
},
Fetch(service: "soundtracks") {
{
featuredPlaylists {
name
}
}
},
},
}

We won't worry too much about the syntax–the knows what's going on! But this is useful when we start to involve more and more complex queries that need optimization.

For this particular , we can see that the recipe and its subfields are coming from the recipes , and the featuredPlaylists and its subfields are coming from the soundtracks . Both of those smaller are run in parallel and resolved by its own subgraph, and the takes care of bundling them up to return in one single response back to the client.

Adding a was pretty straightforward! But right now, you might be feeling that the data in both subgraphs feel separate and siloed. There's nothing directly connecting soundtracks to a particular recipe. We want to be cooking with the perfect playlists after all!

The new feature: a recipe's recommended playlists

We want to ask for details about a specific recipe: its description, instructions, and ingredients, plus recommended playlists to cook with! For each playlist, we want to see the list of tracks as well.

Music Matcher Mockup of a recipe and recommended playlists

Take a few moments to examine the mockup above and practice a schema-first design approach. Here are some questions for you to think about:

  • How would you design your to satisfy the data needs of this page?
  • What already exists in our API? What can we add to it?
  • What might the look like for this page?

Schema-first design

Ready? Here's what pieces of data (types and in our schema) that the page needs:

Music Matcher Mockup of a recipe and recommended playlists - breakdown of data

And what each playlist needs:

Music Matcher Mockup playlists - breakdown of data

The dream query

Finally, here's what the for that page could look like:

The dream query
query GetRecipeAndRecommendedSoundtracks {
randomRecipe {
id
name
description
ingredients {
text
}
instructions
recommendedPlaylists {
id
name
description
tracks {
id
name
explicit
durationMs
}
}
}
}

Note: Curious what this term "dream " comes from? Check out Yelp's blog post on the topic for more detail.

Ideally, we would work with the frontend client teams to decide on and validate this . Here, we've made the decision that the page returns the details of a random recipe (through the randomRecipe ), and that particular recipe will have a field called recommendedPlaylists.

This new recommendedPlaylists for the Recipe type should be the responsibility of the soundtracks , which contains all things related to playlists and tracks!

So we'll need a way to connect the data between both to make our dream work (hint: it's called entities!).

But first, let's set up our local development environment to ensure that the changes we make to the soundtracks not only work correctly but also play nicely with the recipes .

Practice

To add a new subgraph, which of these values does GraphOS need to know?

Key takeaways

  • To add a new , we can use the Studio UI or .
  • We can view the 's using Explorer.

Up next

Let's set ourselves up for local development in the next lesson.

Previous

Share your questions and comments about this lesson

This course is currently in

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