Sorting
The sort
query parameter is used to determine by which property the results collection will be
oredered. Sorting is ascending by default and can be reversed by adding a hyphen (-
) to the start
of the property name.
All sorts have to be explicitly allowed by passing an array to the allowedSorts
method. The
allowedSorts
method takes an array of column names as strings or AllowedSort
instances.
Basic Usage
Section titled “Basic Usage”// GET /users?sort=-name const users = await User.query().allowedSorts('name'); // users will be sorted by name and descending (Z to A)
The define a default sort parameter that should be applied without explicitly adding it to the
request, you can use the defaultSort
method.
// GET /users const users = await User.query().allowedSorts('name', 'street').defaultSort('name'); // will retrieve the users sorted by name
You can use -
if you want to have the default order sorted descendingly.
// GET /users const users = await User.query().allowedSorts('name', 'street').defaultSort('-name'); // will retrieve the users sorted by name descendingly
You can define multiple default sorts
// GET /users const users = await User.query().allowedSorts('name', 'street').defaultSort(['name', '-street']); // will retrieve the users sorted by street descendingly and name ascending
You can sort by multiple properties by separating them with a comma:
// GET /users?sort=name,-street const users = await User.query().allowedSorts('name', 'street'); // users will be sorted by name ascending and street descendingly
Disallowed sorts
Section titled “Disallowed sorts”When trying to sort by a property that’s not specified in allowedSorts
, an InvalidSortQuery
exception will be thrown.
// GET /users?sort=password const users = await User.query().allowedSorts('name'); // Will throw an `InvalidSortQuery` exception as `password` is not allowed sorting property
Custom sorts
Section titled “Custom sorts”You can specify custom sorting methods using the AllowedSort.custom
method. Custom sorts are
instances of invokable classes than implement the Sort
interface. The handle
method will receive
the current query builder instance, the direction to sort in and the sort’s name. This way you can
build any query your heart desires.
For example sorting by string column length:
import { type ModelQueryBuilderContract, type LucidModel } from '@adonisjs/lucid/types/model'; import { type Sort } from '@eienjs/adonisjs-api-query/types'; export default class StringLengthSort<Model extends LucidModel> implements Sort<Model> { public handle( query: ModelQueryBuilderContract<Model>, descending: boolean, property: string, ): void { const direction = descending ? 'desc' : 'asc'; void query.orderByRaw(`LENGTH(${property}) ${direction}`); } }
The custom StringLengthSort
sort class can then be used like this to sort by the length of the
users.name
column:
// GET /users?sort=nameLength const users = await User.query().allowedSorts( AllowedSort.custom('nameLength', new StringLengthSort(), 'name'), ); // The requested `nameLength` sort alias will invoke `StringLengthSort` with the `name` column name.
To change the default direction of the sort you can use defaultDirection
:
const customSort = AllowedSort.custom('customSort', new SentSort()).defaultDirection( SortDirection.Descending, ); const users = await User.query().allowedSorts(customSort).defaultSort(customSort);
Using an alias for sorting
Section titled “Using an alias for sorting”There may be occasions where it is not appropriate to expose the column name to the user.
Similar to using an alias when filtering, you can do this for sorts as well.
The column name can be passed as optional parameter and defaults to the property string.
// GET /users?sort=-street const users = await User.query().allowedSorts(AllowedSort.field('street', 'actualColumnStreet'));