Sorting & Pagination
Sorting with $orderby
$orderby=field [asc|desc][,field [asc|desc]]GET /api/prod/Products?$orderby=Name
GET /api/prod/Products?$orderby=Price desc
GET /api/prod/Orders?$orderby=CustomerCode,OrderDate desc,Priority ascAscending is the default; fields are applied in the listed order, before paging. Only columns in AllowedColumns can be sorted on. Null placement follows the database.
Paging with $top and $skip
| Option | Default | Behavior |
|---|---|---|
$top |
10 |
Maximum rows; limited to the endpoint's MaxPageSize when set |
$skip |
0 |
Rows skipped before the first returned row |
GET /api/prod/Orders?$top=25&$skip=25&$orderby=OrderDate descPaging requires an $orderby that is stable; add a unique column as the last sort key:
GET /api/prod/Products?$orderby=Price desc,ItemCode&$top=20&$skip=0nextLink
When more rows exist, the response includes nextLink with the next page URL; the last page has "nextLink": null. Response format: OData.
The total number of matching rows is returned with $count=true (OData).
Deep pages
Large $skip values make the database read and discard the skipped rows. Keyset paging filters on the last returned key instead:
# Offset
GET /api/prod/Products?$orderby=ItemCode&$top=20&$skip=10000
# Keyset
GET /api/prod/Products?$filter=ItemCode gt 'PROD10000'&$orderby=ItemCode&$top=20Errors
Malformed $orderby and unknown columns return 400 with "Invalid OData query. Check $filter, $select, $orderby and $expand syntax.".
Portway