Thinkific's GraphQL API follows the Relay pattern for Pagination to provide a consistent pattern for slicing and paginating through a set of results. This specification includes some standardized types: Connections, Edges and PageInfo.
A Connection type name will always be suffixed with "Connection" and will include edges, nodes and pageInfo fields. In the example below, we have a GraphQL schema that defines a courses field on a Site type which returns a CourseConnection type, connecting all courses that belong to the current Site.
An Edge is the line from the Connection to a single Node, which in this example represents a single Course object.
# An example GraphQL schema
type Site {
courses(
after: String
before: String
first: Int
last: Int
): CourseConnection!
}
type CourseConnection {
edges: [CourseEdge]
nodes: [Course]
pageInfo: PageInfo!
}
type PageInfo{
endCursor: String
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
}
To make a query using a Connection, you can pass any of the arguments in the above noted schema (i.e. after, before, first, last), but it must include either a first
or last
argument.
- Pass either first or last to specify the number of items you want returned (e.g. first: 10 returns the first 10 courses)
- Use after or before to specify a cursor when paginating through a Connection
In the query below:
- `endCursor` returns a String that represents the cursor of the last item in the current list of courses
- `hasNextPage` returns a boolean that indicates whether there are additional records beyond the current list of courses
# A query using the CoursesConnection with pagination
query CoursesPaginationExample {
site {
courses (first: 2, after: $courseCursor) {
edges {
node {
id
name
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
You can continue to paginate through the list of courses by passing the `endCursor` as an argument to `after` in subsequent requests. A typical response for such a query may be:
{
"data": {
"site": {
"courses": {
"edges": [
{
"node": {
"id": "1638969",
"name": "Advanced Flossing"
}
},
{
"node": {
"id": "1631202",
"name": "Introduction to Flossing"
}
}
],
"pageInfo": {
"endCursor": "Nw",
"hasNextPage": false
}
}
}
},
"extensions": {
"rateLimit": {
"cost": 3,
"remaining": 1997,
"resetAt": "2024-04-01T21:23:00.000Z",
"limit": 2000
}
}
}
Some connections may offer the ability to order the paginated results by a specified field in a specified direction. This optional argument will allow you to sort your results by either ascending or descending based on the field. The `orderBy.field` type will be an enum that will specify the sortable fields for that connection.
If that field contains a null value for one of its records, the null value will be returned first when sorting ascending. When sorting in descending order, nulls will be returned last.
In the query below:
- `orderBy` is supplied to the `members` connection, and is a hash containing 2 key/value pairs
- `direction` is an enum with values of either `ASC` or `DESC`
- `field` is an enum with values specific to the connection. Not all fields will be sortable.
- Since we’re sorting “ASC”, any community members that have a null `activatedAt` field will be returned first before records that have a valid value.
# A query using the CommunityUserConnection with pagination
query communityUsers {
community(id: $id) {
members (first: 2, after: $memberCursor, orderBy:{ direction: “ASC”, field: “ACTIVATED_AT” }) {
edges {
node {
id
activatedAt
user {
firstName
}
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
For more information on GraphQL pagination, see here.