Sorting
Table of contents
All returned collections MUST be sorted, which it means that the order is deterministic: the same request MUST return items in the same order.
Client-controlled sorting
Client-controlled sorting MUST use the query parameter sort.
| Parameter | Type | Description |
|---|---|---|
sort | string | The field(s) to sort on. |
Example:
GET /api/v1/bus-stops?sort=name
Sort field and direction
A sort value is a field name, optionally followed by a comma (,) and a sort direction, either asc (ascending) or desc (descending):
GET /api/v1/bus-stops?sort=name,asc
- If the direction is omitted, the direction MUST default to
asc. - The direction tokens
ascanddescMUST be treated as case-insensitive.
Sorting on multiple fields
You MAY allow sorting on multiple fields by repeating the sort parameter:
GET /api/v1/bus-stops?sort=name&sort=created
Each field MAY have its own direction:
GET /api/v1/bus-stops?sort=name,asc&sort=created,desc
Allowed sort fields
You MUST document which fields are sortable.
Case sensitivity, collation and null ordering
- For string fields, the API SHOULD document whether sorting is case-sensitive and which collation/locale is used. For Norwegian data, sorting SHOULD order the letters
æ,øandåaccording to Norwegian collation rules. - The API SHOULD document where
nullor missing values are placed (sorted first or last).
Tiebreaking
To achieve a deterministic order, the sorting implementation MUST append a unique field with a stable value (typically id) as a final tiebreaker. For example, if a client requests sorting on name and name is not unique across all items, a secondary sort MUST also be applied on a unique field.
Example
GET /item/v1/items?sort=name,asc
{
"items": [
{
"id": "100",
"name": "Item A"
},
{
"id": "101",
"name": "Item A"
},
{
"id": "99",
"name": "Item B"
}
]
}
In this example, the client requested items sorted on name ascending. There are two items with the name “Item A” but the backend applies a secondary sort on id, so they are always returned in the same order (100 before 101). The item with id 99 is still returned last, because the primary sort is on name and “Item B” sorts after “Item A”.
Documenting in OpenAPI
The documentation requirements above (allowed sort fields, default order, case sensitivity, collation and null ordering) MUST be expressed on the sort query parameter in your OpenAPI specification.
Example
{
"parameters": [
{
"name": "sort",
"in": "query",
"description": "Field(s) to sort on. Repeat the parameter to sort on multiple fields. Each value is a field name optionally followed by a direction: `<field>,<asc|desc>`.\n\n**Sortable fields:** `name`, `created`.\n\n**Collation:** String fields are sorted case-insensitively using Norwegian collation.\n\n**Null ordering:** Items with a `null` or missing value for the sort field are placed last, regardless of sort direction.",
"schema": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(name|created)(,(asc|desc))?$"
},
"default": ["name,asc"],
"example": ["name,asc", "created,desc"]
}
}
]
}
Sorting not controlled by client
When returning a collection, there is no requirement that the client can control the sorting. When sorting is not controlled by the client, you MUST however document the order on the response field for the collection:
Example
{
"items": {
"type": "array",
"description": "Sorted by `name` ascending, with `id` as a tiebreaker.",
"items": {
"$ref": "#/components/schemas/Item"
}
}
}