Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

GraphQL pagination

In this guide you will learn how to implement pagination in your GraphQL API.

When working with a large record set, you may want to only fetch the first N number of items. For example, let's start with a basic GraphQL schema for a Todo app:

type Todo @model {
id: ID!
title: String!
description: String
}

When the API is created with an @model directive, the following queries will automatically be created for you:

type Query {
getTodo(id: ID!): Todo
listTodos(
filter: ModelTodoFilterInput
limit: Int
nextToken: String
): ModelTodoConnection
}

Next, take a look at the ModelTodoConnection type to get an idea of the data that will be returned when the listTodos query is run:

type ModelTodoConnection {
items: [Todo]
nextToken: String
}

When querying the API using the listTodos query, the return type will be of ModelTodoConnection, meaning you can return both an array of Todos and a nextToken.

The nextToken is what is used to handle pagination. If the nextToken is null, that means that there is no more data to return from the API. If the nextToken is present, you can use the value as an argument to the next listTodos query to return the next selection set from the API.

To test this out, try creating 5 todos using a mutation like this:

mutation createTodo {
createTodo(input: {
title: "Todo 1"
description: "My first todo"
}) {
id
title
description
}
}

Next, you can set the limit of the number of todos in a query by passing in a limit argument. In this query, you'll set the limit to 2 items and request a nextToken as a return value:

query listTodos {
listTodos(limit: 2) {
items {
id
title
description
}
nextToken
}
}

Now, to query the next 2 items from the API, you can pass this nextToken as the argument:

query listTodos {
listTodos(limit: 2, nextToken: <your_token>) {
items {
id
title
description
}
nextToken
}
}

When there are no other items left to be returned, the nextToken in the response will be set to null.

Querying from a JavaScript application

The listTodos query should have been created for you automatically by the CLI, but for reference purposes it should look something like this:

const listTodos = `
query listTodos($limit: Int) {
listTodos(limit: $limit) {
items {
id
title
description
}
nextToken
}
}
`

To pass in a limit in a query from a JavaScript application, you can use the following code by setting the limit as a variable:

import { API } from 'aws-amplify';
async function fetchTodos() {
const todoData = await API.graphql({
query: listTodos,
variables: {
limit: 2
}
})
console.log({ todoData })
}

The data returned from the API request should look like this (with the items array containing however many items have been created):

{
"data" {
"listTodos" {
"items": [{ id: "001", title: "Todo 1", description: "My first todo" }],
"nextToken": "<token-id>"
}
}
}

To set the nextToken in a query from a JavaScript application, you can use the following code:

import { API } from 'aws-amplify';
async function fetchTodos() {
const todoData = await API.graphql({
query: listTodos,
variables: {
limit: 2,
nextToken: "<token-id>"
}
})
console.log({ todoData })
}