Features

Sorting

Sort Lucid queries by single or multiple columns, aliases, default sorts, and custom callbacks.

The sort query parameter allows clients to order query results by one or more fields in ascending or descending order. Prefixing a sort field with a hyphen (-) sorts in descending (DESC) order.

All sorts must be explicitly allowed via .allowedSorts() on the query builder or via the sorts property on a Filterable Class.

Basic Usage

Pass column names to .allowedSorts():

// GET /users?sort=name -> ORDER BY `name` ASC
// GET /users?sort=-createdAt -> ORDER BY `created_at` DESC
// GET /users?sort=role,-createdAt -> ORDER BY `role` ASC, `created_at` DESC
const users = await User.query()
  .withRequest(request)
  .allowedSorts('name', 'role', 'createdAt');
// Or pass an array:
// .allowedSorts(['name', 'role', 'createdAt'])

If a client requests a sort field that is not in .allowedSorts(), an InvalidSortQuery exception (400 Bad Request) is thrown unless disableInvalidSortQueryException is enabled in Configuration.

Default Sorts

Use .defaultSort() to specify the fallback ordering when the client does not provide a sort query parameter:

import { AllowedSort } from '@eienjs/adonisjs-api-query';

// When GET /users has no ?sort= parameter, orders by `created_at` DESC, then `name` ASC
const users = await User.query()
  .withRequest(request)
  .allowedSorts('name', 'createdAt')
  .defaultSort('-createdAt', 'name');

You can also pass AllowedSort instances to .defaultSort():

const users = await User.query()
  .withRequest(request)
  .allowedSorts('name', 'createdAt')
  .defaultSort(AllowedSort.field('createdAt').setDefaultDirection('desc'));

Sorting by Internal Column Name (Aliases)

Use AllowedSort.field(name, internalName) to expose an alias in the URL that maps to a different column on your model:

import { AllowedSort } from '@eienjs/adonisjs-api-query';

// GET /users?sort=-joined -> ORDER BY `created_at` DESC
const users = await User.query()
  .withRequest(request)
  .allowedSorts([
    AllowedSort.field('joined', 'createdAt'),
    AllowedSort.field('full_name', 'name'),
  ]);

Default Sort Direction on AllowedSort

You can configure a default direction on an AllowedSort instance using .setDefaultDirection() or by prefixing the name with -:

import { AllowedSort, SortDirection } from '@eienjs/adonisjs-api-query';

const sort = AllowedSort.field('createdAt').setDefaultDirection(SortDirection.Descending);

Callback Sorts

Use AllowedSort.callback() when you need custom ORDER BY expressions, raw SQL ordering, or aggregate sorting:

import { AllowedSort } from '@eienjs/adonisjs-api-query';

// GET /users?sort=-postsCount
const users = await User.query()
  .withRequest(request)
  .withCount('posts')
  .allowedSorts([
    AllowedSort.callback('postsCount', (query, isDescending) => {
      void query.orderBy('posts_count', isDescending ? 'desc' : 'asc');
    }),
  ]);

Custom Sort Classes

For reusable sorting logic across multiple queries or models, implement the Sort<Model> interface and register it with AllowedSort.custom(). See Custom Filters, Sorts & Includes for an example.