REST API Pagination, Filtering, and Sorting Done Right
Design predictable REST collection endpoints with pagination, filtering, sorting, validation, stable cursors, and clear response contracts.
On this page
Collection endpoints become difficult when clients need pagination, filtering, sorting, and consistent behavior while data changes. A clear contract keeps both the client and database implementation manageable.
#Bound every collection
Never allow an unbounded list by default. Accept a validated page size with a maximum and return enough metadata for the client to continue. A default limit protects the database from accidental large reads.
#Offset versus cursor pagination
Offset pagination is simple and useful for small, mostly stable collections. As offsets grow or records change frequently, cursor pagination can provide more stable traversal. A cursor should be opaque, signed or validated, and tied to a deterministic ordering.
#Filtering and sorting
Allowlist filter fields and operators rather than passing arbitrary SQL fragments. Define how empty values, case sensitivity, dates, and invalid filters behave. Allowlist sort fields and always include a unique tie-breaker for stable ordering.
#Response shape
Return a consistent collection envelope containing items and pagination information. Document whether totals are exact, estimated, or omitted. A total-count query can be expensive and may not be needed for every interface.
#Database alignment
Index common filters and orderings, inspect query plans, and cap expensive combinations. Do not expose a flexible API that the database cannot serve safely. Add rate limits and timeouts for complex queries.
#Frequently asked questions
#Should an API always return total pages?
No. Exact counts can be costly; return them when the product needs them and the database can support them.
#Are cursors safer than offsets?
They can provide more stable traversal for changing data, but they require a clear ordering and cursor contract.
#Conclusion
Good collection APIs are bounded, explicit, and aligned with their database access patterns. Choose pagination deliberately, validate filters and sort fields, use stable ordering, and document the contract.