Overview
We know which endpoint we need and how the $batch
variable works.
In this lesson, we will:
- Learn how to configure the
$batch
variable in a Connector to map query parameters - Use the Connectors Debugger to examine the results of batching
The listings batch endpoint
For our Airlock project, we'll use this batch endpoint: GET /listings?id=[id]
.
Let's give it a try. In the browser, paste in the following request: https://airlock-listings.demo-api.apollo.dev/listings/batch?id=listing-3&id=listing-2&id=listing-5
Here, we're asking for three different listings, with each listing id
defined as a query parameter.
The JSON object response gives us an array of listing objects, in the order we've listed in the request (listing-3
, listing-2
, listing-5
).
It's exactly what we need! Time to use it in our schema.
Using $batch
in the Connector
First, we'll find the
Listing
type in our schema. Currently, we've configured the Connector to send a request toGET /listings/:id
. We'll need to replace this with a request to our batch endpoint.type Listing@connect(source: "listings"http: { GET: "/listings/{$this.id}" }selection: """idtitlenumOfBedscostPerNightdescriptionphotoThumbnaillatitudelongitude""")@key(fields: "id") {id: ID!"The listing's title"title: String!"The number of beds available"numOfBeds: Int"The cost per night"costPerNight: Float"The listing's description"description: String"The thumbnail image for the listing"photoThumbnail: String"Latitude coordinates for the destination"latitude: Float"Longitude coordinates for the destination"longitude: Float}Let's start by removing the path parameter
$this.id
. In its place, we'll add on thebatch
path to match our batch endpoint.http: {GET: "/listings/batch",}Next, we'll fill in the query parameter values using
queryParams
.http: {GET: "/listings/batch",queryParams: """"""}Our endpoint needs query parameters for
id
, referring to the listing'sid
field. To define this mapping, we'll set the query parameter name (id
) to the value of$batch.id
.http: {GET: "/listings/batch",queryParams: """id: $batch.id"""}With this syntax, we've configured our Connector to make a call to
GET /listings/batch
, and the router will take care of gathering up all those listingid
fields before making one call to the batch endpoint using those values.
Checking our work
Let's save our changes and jump over to Sandbox.
We'll run the same operation as before:
query GetFeaturedListings {featuredListings {idtitlenumOfBedscostPerNightdescriptionphotoThumbnaillatitudelongitude}}
Run the request, and we get the same data back. That's good—nothing should have changed in our data.
But let's look at the real magic behind the scenes! We'll navigate to the Connectors Debugger.
We only have two requests now: one to our first endpoint (GET /featured-listings
), and another to our batched endpoint, which asks for details from multiple listings (GET /listings/batch?id=listing-1&id=listing-2&id=listing-3
).
We've successfully solved our N+1 problem!
In the original approach without batching, the router had to make N separate requests to our REST endpoint to retrieve data for each listing entity.
With $batch
, the router recognizes that when it needs to retrieve data for one or more listing entities, it can make one request with all the id
s.
Practice
Key takeaways
- With
$batch
, the router can group similar requests into one, reducing network calls and solving the N+1 problem.
Conclusion
And with that, we've done it—we've tackled the N+1 problem! With $batch
in our Connectors toolbelt, we can boost our graph's performance. We've taken a basic data-fetching strategy and made it into something that can scale with our queries and features.
Looking to do more with Connectors?
Try our course "Expressions in Connectors: Mapping and Transforms" for more hands-on practice with transforming JSON responses to selection mappings.
Join us in the Apollo Community to chat about what we're building with Apollo and Connectors.
See you in the next one!
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.