Implementing Sorting
1. Using Sort Query Parameter
| Pattern | Example |
| Single field | ?sort=name |
| Multi-field | ?sort=name,createdAt |
| Object style | ?sort[name]=asc&sort[createdAt]=desc |
2. Implementing Multi-Field Sorting
Example: Multi-Field Sort
GET /users?sort=-createdAt,name
# 1. createdAt DESC
# 2. name ASC (tie-breaker)
3. Specifying Sort Direction
| Style | Ascending | Descending |
| Prefix | +name (or no prefix) | -name |
| Suffix | name:asc | name:desc |
| Param | sort=name&order=asc | sort=name&order=desc |
4. Using Plus/Minus Prefix
JSON:API standard convention.
| Param | Result |
?sort=name | Ascending (default) |
?sort=-name | Descending |
?sort=-createdAt,+name | Date desc, name asc |
5. Implementing Default Sorting Order
| Resource | Sensible Default |
| Time-series data | -createdAt (newest first) |
| User-facing lists | Name ASC |
| Search results | Relevance score DESC |
| Always | Include stable tie-breaker (id) for pagination consistency |
6. Handling Invalid Sort Fields
| Approach | Trade-off |
| 400 Bad Request | Strict; client must fix |
| Ignore + warn header | Lenient; less helpful |
| Whitelist fields | Required for SQL injection safety |
Warning: Without a stable sort, pagination may skip/duplicate rows. Always append unique tie-breaker.
Example: Stable Sort
ORDER BY created_at DESC, id DESC
LIMIT 20 OFFSET 40;
8. Implementing Nested Field Sorting
| Syntax | Example |
| Dot notation | ?sort=address.city |
| JSON:API | ?sort=author.name |
| Implementation | SQL JOIN + ORDER BY joined column |
9. Documenting Sortable Fields
| Documentation | Field |
OpenAPI enum | List sortable field names |
| Default order | State explicitly |
| Performance notes | Indexed vs non-indexed columns |
| Technique | Benefit |
| Composite index on (sortField, id) | Index scan, no sort step |
| Covering index | Index-only scan |
| Limit scan with WHERE | Reduce rows before sort |
| Cache top-N results | Hot pages of feeds |