Over the last few days, I’ve broken up pagination into a few mini-topics, each of which plays an important part in designing a good pagination system in GraphQL:
cursor
andlimit
arguments into our query resolversreturning Connections rather than lists directly. Allows us to:
Return both edges and nodes (can put metadata on edges).
Return a pageInfo object that tells the client:
cursor
hasNextPage
using opaque cursors
to make it clear to the client not to depend on any particular type of data format on the cursor
The cursor is just a cursor to the client
Allows us to re-use the PageInfo type, as it just takes a cursor string and doesn’t care what the underlying format of the cursor is (when the resolver has decoded it into a createdAt date, for example).
So, on this lovely Friday morning in Burma, I’d like to just go through the exercise of implementing pagination all the way through, this time on Comments
that belong to a Post
.
Each Post
can have multiple comments that belong to it. We want to allow the client to say:
“Give me the first 3 comments that belong to this post”
“Ok, the user wants to see more comments. Give me the next 3 comments. Here’s the last comment they saw, so start after that.”
Let’s get started.
Schema
Add the
PostCommentConnection
to our schema.Holds the data + pageInfo returned by the query
Add the
PostCommentEdge
to our schema. This holds:Edges
Nodes
Optional metadata on the edge (data relevant to the relationship itself, rather than the node)
The
comments
field on our rootPosts
type should now take two arguments (cursor
andlimit
) and should return aPostCommentConnection
object rather than a list ofComment
objects.
Resolver
Even though we’re building pagination for comments, we’re not working on the comment resolvers themselves, we’re actually working on the comment field resolver on the root Post object.
When the client is asking the API to describe a given post object, we want the client to optionally provide pagination arguments like this:
query { post(id: 1) { text comments(limit: 3) { # snazzy ... } } }
So in our Post type resolvers, we work inside the custom resolver for the Comment field:
And that’s all the server code we need to (get to?) write.
We can then test it out in GraphQL Playground and see that our new comment pagination system works swimmingly.