Sorting pagination
Sorting & Pagination
When to Use
Sorting: Control result order. Essential for chronological listings, alphabetical lists, and custom ordering.
Pagination: Break large result sets into pages. Required for collections that can grow unbounded.
Sorting Syntax
| Pattern | Description | Example |
|---|---|---|
?sort=field |
Sort ascending by field | ?sort=title |
?sort=-field |
Sort descending by field | ?sort=-created |
?sort=field1,field2 |
Multi-field sort | ?sort=-created,title |
?sort=relationship.field |
Sort by relationship field | ?sort=uid.name |
Sorting Examples
# Newest articles first
GET /jsonapi/node/article?sort=-created
# Alphabetical by title
GET /jsonapi/node/article?sort=title
# Newest first, then alphabetical
GET /jsonapi/node/article?sort=-created,title
# Sort by author name
GET /jsonapi/node/article?sort=uid.name
Pagination Syntax
| Parameter | Description | Default |
|---|---|---|
page[limit] |
Items per page | 50 |
page[offset] |
Skip N items | 0 |
Offset-based pagination:
Page 1: ?page[limit]=25&page[offset]=0
Page 2: ?page[limit]=25&page[offset]=25
Page 3: ?page[limit]=25&page[offset]=50
Pagination Response
JSON:API includes pagination links:
{
"data": [...],
"links": {
"self": { "href": "...?page[offset]=0&page[limit]=25" },
"first": { "href": "...?page[offset]=0&page[limit]=25" },
"prev": { "href": "...?page[offset]=0&page[limit]=25" },
"next": { "href": "...?page[offset]=25&page[limit]=25" },
"last": { "href": "...?page[offset]=100&page[limit]=25" }
}
}
Pattern
Paginated, sorted collection:
# Published articles, newest first, 10 per page
GET /jsonapi/node/article?filter[status]=1&sort=-created&page[limit]=10&page[offset]=0
Client-side pagination loop:
async function fetchAllArticles() {
let articles = [];
let nextUrl = '/jsonapi/node/article?page[limit]=50';
while (nextUrl) {
const response = await fetch(nextUrl, {
headers: { 'Accept': 'application/vnd.api+json' }
});
const data = await response.json();
articles = articles.concat(data.data);
nextUrl = data.links.next?.href || null;
}
return articles;
}
Common Mistakes
Not implementing pagination: Fetching unbounded collections can timeout or exhaust memory. WHY: Large sites have thousands of nodes. Always use page[limit].
Using huge page limits: Setting page[limit]=1000 defeats pagination purpose. WHY: Performance degrades with large pages. Stick to 10-50 items.
Sorting by non-indexed fields: Sorting by body text or complex fields is slow. WHY: Database can't efficiently sort non-indexed columns. Sort by created, title, or indexed fields.
Forgetting to handle missing next link: When links.next is absent, you're on the last page. WHY: No more results exist. Check for link existence before fetching.
Combining offset pagination with rapidly changing data: Items can appear twice or get skipped. WHY: If new items are created between requests, offsets shift. For real-time data, use cursor-based pagination (requires custom implementation).