Overview
Project all set up? Let's get going!
In this lesson, we will:
- Explore the project's schema
- Use the Connectors Debugger in Sandbox to inspect our Connector requests
- Identify how the N+1 problem appears in our project
The schema
Let's take a closer look at the current state of our Airlock schema in listings.graphql
.
We have one entry point into our graph: Query.featuredListings
, which returns a list of Listing
types. The Connector populates that data by making a request to the GET /featured-listings
endpoint, and maps the response for a few fields (id
, title
, numOfBeds
, and costPerNight
).
type Query {"A curated array of listings to feature on the homepage"featuredListings: [Listing!]!@connect(source: "listings"http: { GET: "/featured-listings" }selection: """idtitlenumOfBedscostPerNight""")}
The Listing
type is an entity with its own Connector, which makes a request to the GET /listings/:id
endpoint. It maps the response for all the fields in the type, more than what the Query.featuredListings
Connector by itself can provide.
Note: Check out the Apollo documentation for a refresher on what entities are.
"A particular intergalactic location available for booking"type Listing@connect(source: "listings"http: { GET: "/listings/{$this.id}" }selection: """idtitlenumOfBedscostPerNightdescriptionphotoThumbnaillatitudelongitude""")@key(fields: "id") {# ...Listing fields}
Let's explore this schema with Sandbox and start sending queries!
N+1 requests
Open up http://localhost:4000 in the browser, where the local Sandbox is running our graph.
Let's build a query that asks for just a few fields:
query GetFeaturedListings {featuredListings {idtitlenumOfBedscostPerNight}}
When we run this query, we'll get some data back! Let's take a peek behind the scenes at where this data is coming from.
Navigate to the Connectors Debugger by hitting the arrow beside Response.
From here, we can see we have one request to GET /featured-listings
. Great! That's exactly what the schema told us would happen.
But our UI mockup needs more than just those four fields. We need the description
, photoThumbnail
, latitude
, and longitude
fields, too. Let's add those to our query and see what happens.
query GetFeaturedListings {featuredListings {idtitlenumOfBedscostPerNightdescriptionphotoThumbnaillatitudelongitude}}
We'll run it again… and the Connectors Debugger shows us more requests!
This time, we've got three more requests: one for each listing object returned by the Query.featuredListings
Connector. Because that Connector can't fulfill all of the fields defined in the query, the router goes to the Listing
entity Connector for help. The Listing
entity Connector takes care of making a request to GET /listings/:id
, for each ID, and returns the rest of the fields.
In this case, those three requests represent the N in our N+1 problem. This doesn't look too bad, but we want to get ahead of any potential performance issues before it gets worse! If our featured listings increase without warning, those three additional requests will also grow accordingly.
Practice
Key takeaways
- A Connector for an entity type can retrieve all the fields for that type.
Up next
Now that we've seen the N+1 problem in action, it's time to do something about it. In the next lesson, you'll dive into batch endpoints and how to define them in a Connector.
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.