Pagination

Handling lists the GraphQL way — paginate with connections

When working with the API, you will frequently encounter lists of resources. These lists are returned as connections, which provide a consistent interface for pagination.

Connections originate from the Relay specification and are now widely adopted within the GraphQL community as a best practice for representing paginated collections.

Connection Arguments

Every connection supports the following pagination arguments:

  • first — Return the first n items.

  • after — Return items after a given cursor (typically used with first).

  • last — Return the last n items.

  • before — Return items before a given cursor (typically used with last).

Note: Both first and last may be subject to maximum limits. These limits vary by connection and are documented in the schema reference or visible within the GraphiQL documentation panel.

Connection Structure

Each connection contains two key elements:

  • pageInfo — Provides metadata necessary for pagination, such as cursors and information about the availability of additional pages.

  • edges — A list of edges, each representing an object in the collection, including its cursor and associated node.

Example: User Projects

The following query fetches the first three projects for a given user:

{
  user {
    projects(first: 3) {
      pageInfo {
        hasNextPage
        endCursor
      }
      edges {
        cursor
        node {
          pk
          name
        }
      }
    }
  }
}

In this example, the return type of projects is ProjectConnection.

  • The argument first: 3 instructs the server to return the first three projects.

  • The pageInfo object indicates whether additional results exist (hasNextPage) and provides the cursor of the last item (endCursor).

  • Each edge contains a cursor and the project node itself (pk, name).

Paginating Through Results

To request the next page, use the endCursor from the previous response as the value for the after argument:

{
  user {
    projects(first: 3, after: "<endCursor>") {
      ...
    }
  }
}

To paginate in the opposite direction, request the last n items and use the startCursor as the before argument.