5. Filtering, Sorting, Pagination
5. Filtering, Sorting, Pagination
Large collections will crush your API if you return every record in a single response. Filtering, sorting, and pagination give clients control over exactly what data they receive and in what order.
Filtering
Clients filter collections by passing criteria as query parameters. Use the field name as the parameter name and the desired value as its value:
GET /products?category=electronics&brand=acme
GET /users?status=active&role=admin
For more expressive filtering (range queries, partial matches), consider a dedicated syntax such as filter[price][gte]=50 or a lightweight query language documented in your API specification.
Sorting
Let clients choose the sort order using a sort parameter. Prefix the field name with a minus sign to indicate descending order:
GET /products?sort=price # ascending by price
GET /products?sort=-price # descending by price
GET /products?sort=-created_at # newest first
Support multiple sort keys where it makes sense, separated by commas:
GET /products?sort=category,-price
Pagination
Always paginate list endpoints. Returning unbounded collections wastes bandwidth, slows response times, and can destabilise your database under load.
Offset-Based Pagination
The simplest approach. Use page and per_page parameters:
GET /products?page=2&per_page=20
Set a sensible default for per_page (20–50 is typical) and enforce a hard maximum (e.g. 100) so clients cannot request thousands of records in one call.
Cursor-Based Pagination
For very large datasets or real-time feeds, cursor-based pagination is more reliable. Instead of calculating an offset, the server returns an opaque cursor that the client passes back to fetch the next page:
GET /products?cursor=eyJpZCI6IDQ2MH0=&per_page=20
Cursor-based pagination avoids the "shifting pages" problem that occurs with offset pagination when records are inserted or deleted between requests.
Combining Everything
These features compose cleanly in a single request:
GET /products?category=electronics&sort=-price&page=1&per_page=25
This returns the first 25 electronics products, sorted by price descending. Document the supported parameters and their defaults clearly in your API specification.