Overview
Let's dive even deeper, and check out how an operation actually gets resolved when connectors are involved.
In this lesson, we will:
- Examine an operation's query plan
- Optimize a connector's selection mapping to save an extra network call
A listing's amenities
Let's take a closer look at that GetListingAmenities
operation from the previous lesson.
query GetListingAmenities($listingId: ID!) {listing(id: $listingId) {idtitleamenities {idnamecategory}}}
We have two connectors doing the work to resolve data for this operation. The first connector we added to Query.listing
and the second to Listing.amenities
.
The router takes care of coordinating these calls using its query plan, the set of instructions the router follows to fetch and assemble data.
Examining the query plan
In Explorer, let's run the operation again. Don't forget to define a
listingId
in the Variables section:query GetListingAmenities($listingId: ID!) {listing(id: $listingId) {idtitleamenities {idnamecategory}}}{"listingId": "listing-9"}Open up the Query Plan panel by clicking on the arrow beside Response.
studio.apollographql.com/sandboxWe can see two fetch calls: one to
GET /listings/{$args.id}
and then a follow-up one toGET /listings/{$this.id!}/amenities
.studio.apollographql.com/sandbox
Optimizing network calls
This is perfectly fine, the extra call to fetch follow-up amenities doesn't look like it's adding much to the response time. But what if we were able to remove the need for an extra call?
Open up the Connectors Debugger panel.
Select the first request to
/listings/listing-9
.studio.apollographql.com/sandboxNavigate to the Response body. We can see the JSON object we get back does contain
amenities
information!studio.apollographql.com/sandboxResponse body{"id": "listing-9","title": "The Nostromo in LV-426","description": "Ever wondered what it must be like to be aboard The Nostromo, minus the Xenomorph? Now you can find out!","costPerNight": 474,"hostId": "user-6","locationType": "HOUSE","numOfBeds": 4,"photoThumbnail": "https://res.cloudinary.com/apollographql/image/upload/v1644353889/odyssey/federation-course2/illustrations/listings-09.png","isFeatured": true,"latitude": 123.989,"longitude": 534.98,"closedForBookings": false,"amenities": [{"id": "am-1","category": "Accommodation Details","name": "Interdimensional wifi"},{"id": "am-2","category": "Accommodation Details","name": "Towel"}// More amenities data...]}Since we already have the data we need from the first request, let's make use of it!
Open up the
listings.graphql
file and find the connector forQuery.listing
.listings.graphqllisting(id: ID!): Listing@connect(source: "v1"http: { GET: "listings/{$args.id}" }selection: """idtitlenumOfBedscostPerNightclosed: closedForBookings""")We'll add to our selection mapping! Following the format of our JSON property, we can add
amenities
to our selection.listings.graphqlselection: """idtitlenumOfBedscostPerNightclosed: closedForBookingsamenities"""If we save our changes right now, we'll get a helpful message from
rover dev
! Makes sense:Amenity
is an object type, so we need to include at least one of its fields in the data we return.rover dev error messageerror[E029]: Encountered 1 build error while trying to build a supergraph.Caused by:GROUP_SELECTION_REQUIRED_FOR_OBJECT: `Listing.amenities` is an object, so``@connect(selection:)` on `Query.listing`` must select a group `amenities{}`.Let's keep adding to the selection. Following the error message, we'll add curly braces. Inside, we can pick the properties we want from each item in our
amenities
array. That includes:id
,category
andname
.listings.graphqlamenities {idcategoryname}Let's save our changes and
rover dev
should compose successfully!
Back to the query plan
With those changes, we should have saved ourselves an extra network call. Let's check our work.
Jump back to Explorer and look at the query plan again for
GetListingAmenities
.query GetListingAmenities($listingId: ID!) {listing(id: $listingId) {idtitleamenities {idnamecategory}}}{"listingId": "listing-9"}Run the operation and examine the Query Plan.
studio.apollographql.com/sandboxOnly one fetch call!
Open up the Connectors Debugger and verify that we only see one request: to the
listings/:id
endpoint.studio.apollographql.com/sandbox
We're down to just one call to our REST API! 🎉
Practice
Key takeaways
- The Query plan option in Explorer lets us inspect how the router plans to resolve a particular operation using connectors, along with the network calls involved.
- With the Connectors Debugger, we can identify opportunities to reduce network calls and streamline our requests!
Up next
We've tackled queries and retrieving read-only data—now it's time to switch our attention over to manipulating data with mutations!
Share your questions and comments about this lesson
This course is currently in
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.