Why use Connections in Pagination?
Directly returning a list of items for a query is nice and simple, but what if we want to send more information to the client with each page query?
For example, we could return not just a list of posts, but also a pageInfo object that tells the client a few things it might like to know:
hasNextPage
lastCursor
We want our client’s query to look something like this:
query { posts(limit: 2) { edges { node { id text } } pageInfo { endCursor } } }
The result of this query would look something like this:
{ "data": { "posts": { "edges": [ { "node": { "id": "3", "text": "Third post." } }, { "node": { "id": "2", "text": "Second post." } } ], "pageInfo": { "endCursor": "2019-06-18T04:22:28.016Z" } } } }
The client not only gets the data it’s looking for as nodes
, but also useful pageInfo
data.
Note: “Edges” and “nodes” are concepts from Graph Theory: a node is a piece of data like a User, Post, or Message, and an edge is a line representing a relationship between two nodes. The Apollo team has an excellent blog post on this topic and how it relates to Connections in GraphQL.
Implementation
Schema
Add PageInfo to the top level schema.
Add PostConnection
and PostEdge
to the Post schema.
Then, return the PostConnection
type from the posts
query.
Note: I like the argument names of Relay-style pagination queries (using “first/since” instead of “limit/cursor”), but that’s a task for another time.
Resolvers
In the posts
query resolver:
Now, the query works as expected in GraphQL Playground. We can run an initial query with no cursor:
Then we can grab the endCursor
from the pageInfo
and use it to fetch our next page:
Possible Improvements
Use opaque cursors as strings instead of dates
We can then use our
PageInfo
type for other connections
Add
hasNextPage
topageInfo
Highlight the power of Connections by using this pattern on querying nested objects
querying comments on a specific post might be a good illustration