Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Pagination with
Pagination narrows large datasets to smaller, manageable pages. In GraphQL, Data API builder (DAB) uses the after argument for keyset pagination, providing stable and efficient traversal through ordered results. Each cursor encodes the position of the last record in the previous page, allowing the next query to continue from that point. Unlike offset pagination, keyset pagination avoids gaps or duplicates when data changes between requests.
Go to the REST version of this document.
Quick glance
| Concept | Description |
|---|---|
after |
The continuation token from the prior request |
first |
The maximum number of records to fetch per page |
hasNextPage |
Indicates whether more data exists |
endCursor |
The token to include in the next after request |
Basic pagination
GraphQL query
In this example we are getting the first three books.
query {
books(first: 3) {
items {
id
title
}
hasNextPage
endCursor
}
}
Conceptual SQL
SELECT TOP (3)
id,
sku_title AS title
FROM dbo.books
ORDER BY id ASC;
Sample response
{
"data": {
"books": {
"items": [
{ "id": 1, "title": "Dune" },
{ "id": 2, "title": "Foundation" },
{ "id": 3, "title": "Hyperion" }
],
"hasNextPage": true,
"endCursor": "eyJpZCI6M30="
}
}
}
Continuation with after
The after argument specifies the continuation token for the next page. The value is a base64-encoded cursor representing the last record from the previous page.
Warning
The after argument carries an opaque token that marks where the previous page ended. Treat tokens as immutable and never attempt to construct or edit them.
In this example we are getting the next three books after the last page’s cursor.
GraphQL query
query {
books(first: 3, after: "eyJpZCI6M30=") {
items {
id
title
}
hasNextPage
endCursor
}
}
Conceptual SQL
SELECT TOP (3)
id,
sku_title AS title
FROM dbo.books
WHERE id > 3
ORDER BY id ASC;
Sample response
{
"data": {
"books": {
"items": [
{ "id": 4, "title": "I, Robot" },
{ "id": 5, "title": "The Left Hand of Darkness" },
{ "id": 6, "title": "The Martian" }
],
"hasNextPage": true,
"endCursor": "eyJpZCI6Nn0="
}
}
}
Nested pagination
Pagination can be applied to related collections, such as retrieving authors with a paged list of books.
GraphQL query
query {
authors {
items {
id
name
books(first: 2) {
items {
id
title
}
hasNextPage
endCursor
}
}
}
}
Conceptual SQL
-- parent
SELECT
id,
name
FROM dbo.authors;
-- child
SELECT TOP (2)
author_id,
id,
sku_title AS title
FROM dbo.books
WHERE author_id IN (@a1, @a2)
ORDER BY id ASC;
Note
Any schema or ordering change invalidates previously issued tokens. Clients must restart pagination from the first page.
Example configuration
{
"runtime": {
"pagination": {
"default-page-size": 100,
"max-page-size": 100000
}
},
"entities": {
"Book": {
"source": {
"type": "table",
"object": "dbo.books"
},
"mappings": {
"sku_title": "title",
"sku_price": "price"
},
"relationships": {
"book_category": {
"cardinality": "one",
"target.entity": "Category",
"source.fields": [ "category_id" ],
"target.fields": [ "id" ]
}
}
},
"Category": {
"source": {
"type": "table",
"object": "dbo.categories"
},
"relationships": {
"category_books": {
"cardinality": "many",
"target.entity": "Book",
"source.fields": [ "id" ],
"target.fields": [ "category_id" ]
}
}
}
}
}
See also
| Concept | REST | GraphQL | Purpose |
|---|---|---|---|
| Projection | $select | items | Choose which fields to return |
| Filtering | $filter | filter | Restrict rows by condition |
| Sorting | $orderby | orderBy | Define the sort order |
| Page size | $first | first | Limit the number of items per page |
| Continuation | $after | after | Continue from the last page using a cursor |
Note
REST keywords begin with $, following OData conventions.