8. Using @defer
3m

Overview

In some , some may take longer to resolve than others. And this might mean our users staring at a loading screen for longer than we'd like.

In this lesson, we will:

  • Learn about the @defer
  • Apply the @defer to a slow in our

Investigating a slow query

Let's take this example of an regularly sent to the Poetic Plates API. The GetRecipePage includes details about a specific recipe, its ingredients and instructions. It also asks for a list of recently added recipes.

query GetRecipePage {
recipe(id: "recOZrH0RhjSjATBp") {
id
name
cookingTime
prepTime
readyTime
servings
instructions
ingredients {
text
}
}
recentlyAddedRecipes {
name
cookingTime
servings
}
}

When we try running this, we can experience for ourselves just how long this query takes. 🐢

From a client app's perspective, the important information is in the recipe details. That's what the users want to see right away! Unfortunately, the recentlyAddedRecipes is slowing everything down. @defer to the rescue!

The @defer directive

The @defer enables our queries to receive data for specific incrementally, instead of waiting to receive all field data at the same time. This is helpful whenever some fields in a take much longer to resolve than others, like the recentlyAddedRecipes and its subfields.

We can only defer certain in our schema, specifically:

  • Root of the Query type (along with their sub)
  • of any type (along with their subfields)

Since recentlyAddedRecipes is a root in our Query type, it matches the first situation and we can safely defer it!

Note: Curious about types? Check out our Odyssey Voyage series.

How to use @defer

To use the @defer , we apply it to in our queries. There's an easy way to do this in Explorer, so we don't have to remember the syntax every time.

With the GetRecipePage open, we'll place our cursor on the we want to defer: recentlyAddedRecipes. Then, right-click and select "Wrap with inline @defer " (or "Extract @defer fragment") and Explorer automatically takes care of the syntax for us.

https://studio.apollographql.com

Explorer with defer options

Our should now look like this:

query GetRecipePage {
recipe(id: "recOZrH0RhjSjATBp") {
id
name
cookingTime
prepTime
readyTime
servings
instructions
ingredients {
text
}
}
... @defer {
recentlyAddedRecipes {
name
cookingTime
servings
}
}
}

Let's run the now.

We can see a new section called "Response Timeline".

https://studio.apollographql.com

Explorer with response timline after defer

When we hover over the first circle, we can see the data about our recipe is returned, but not the recentlyAddedRecipes .

When we hover over the second circle, we can see the additional data returned, a few seconds afterwards.

This is going to make a big difference in our client app experiences.

Note: Clients must support receiving responses as multipart HTTP responses. This functionality is currently supported in for Web and Kotlin (experimental).

Practice

Use the schema below to answer the follow question:

type Query {
availableFruits: [Fruit]
fruit(id: ID): Fruit
randomFruit: Fruit
}
type Mutation {
buyFruit(fruitId: ID): Fruit
}
type Fruit {
id: ID
cost: Float
isInSeason: Boolean
color: String
}
Which of the following fields (and its subfields) can be deferred?
Which of the following statements are true?

Key takeaways

  • The @defer enables our queries to receive data for specific incrementally. We apply it to a in our .
  • comes with built-in support for the @defer .

Conclusion

And there we have it: we've got a ready to receive queries and share the magic of poetic AI-generated recipes!

Awesome job! We've learned what the is and the components that make it work: and a . We created a supergraph using an existing API and now it's set up for success inside . We've got a public ready for API consumers to try out. We've got access to and metrics segmented by clients and we can use defer to improve our user experience.

This is only the beginning; we've had our appetizer, and I hope you're hungry for more!

If you want to learn how to make changes to your safely and confidently, the next course, "GraphOS: Safe API delivery" is for you! See you there! 👋

Previous

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.