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 REST, Data API builder (DAB) uses the $after query parameter for keyset pagination, providing stable and efficient traversal through ordered results. Each token marks the position of the last record from the previous page, allowing the next request to continue from that point. Unlike offset pagination, keyset pagination prevents missing or duplicated rows when data changes between requests.
Go to the GraphQL version of this document.
Quick glance
| Concept | Description |
|---|---|
$after |
The opaque continuation token returned from the prior request |
$first |
The maximum number of records to fetch per page |
nextLink |
URL for the next page includes $after |
Basic pagination
In this example, we're getting the first three books.
HTTP request
GET /api/books?$first=3
Conceptual SQL
SELECT TOP (3)
id,
sku_title AS title
FROM dbo.books
ORDER BY id ASC;
Sample response
{
"value": [
{ "id": 1, "title": "Dune" },
{ "id": 2, "title": "Foundation" },
{ "id": 3, "title": "Hyperion" }
],
"nextLink": "/api/books?$first=3&$after=eyJpZCI6M30="
}
Note
If next-link-relative=true in configuration, nextLink contains a relative path; otherwise, it’s an absolute URL.
Continuation with $after
The $after parameter specifies the continuation token for the next page. The value is a base64-encoded string representing the last record of the previous page.
Warning
$after carries an opaque token that identifies where the last page ended. Treat tokens as immutable and never try to construct or modify them.
In this example, we're getting the next three books after the last page’s token.
HTTP request
GET /api/books?$first=3&$after=eyJpZCI6M30=
Conceptual SQL
SELECT TOP (3)
id,
sku_title AS title
FROM dbo.books
WHERE id > 3
ORDER BY id ASC;
Sample response
{
"value": [
{ "id": 4, "title": "I, Robot" },
{ "id": 5, "title": "The Left Hand of Darkness" },
{ "id": 6, "title": "The Martian" }
],
"nextLink": "/api/books?$first=3&$after=eyJpZCI6Nn0="
}
End of data
When nextLink is absent, there are no more records to fetch.
The final page response includes only a value array without a nextLink.
Sample response
{
"value": [
{ "id": 7, "title": "Rendezvous with Rama" },
{ "id": 8, "title": "The Dispossessed" }
]
}
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.