Sort
Definition
During index requests, usually we have to sort by specific attributes. This requires the $sort
configuration:
class PostRepository extends Repository
{
public static array $sort = ['id'];
Performing request requires the sort query param:
Descending sorting
Sorting DESC requires a minus (-
) sign before the attribute name:
GET: /api/restify/posts?sort=-id
Sorting ASC:
GET: /api/restify/posts?sort=id
or with plus sign before the field:
GET: /api/restify/posts?sort=+id
Sort using relation
Sometimes you may need to sort by a belongsTo
or hasOne
relationship.
This become a breeze with Restify. Firstly you have to instruct your sort to use a relationship:
HasOne sorting
Using a related
relationship, it becomes very easy to define a sortable by has one related.
You simply add the ->sortable()
method to the relationship:
// UserRepository.php
public function related(): array
{
return [
'post' => HasOne::make('post', PostRepository::class)->sortable('title'),
];
}
The sortable
method accepts the column (or fully qualified column name) of the related model.
The API request will always have to use the full path to the attributes
:
GET: /api/restify/posts?sort=post.attributes.title
The structure of the sort
query param value consist always from 3 parts:
post
- the name of the relation defined in therelated
methodattributes
- a generic json:api termtitle
- the column name from the database of the related model
BelongsTo sorting
The belongsTo sorting works in a similar way.
You simply add the ->sortable()
method to the relationship:
// PostRepository.php
public function related(): array
{
return [
'user' => BelongsTo::make('user', UserRepository::class)->sortable('name'),
];
}
Using custom sortable filter
You can override the sorts
method, and return an instance of SortableFilter
that might be instructed to use a relationship:
// PostRepository
use Binaryk\LaravelRestify\Fields\BelongsTo;
use Binaryk\LaravelRestify\Filters\SortableFilter;
public static function sorts(): array
{
return [
'users.name' => SortableFilter::make()
->setColumn('users.name')
->usingRelation(
BelongsTo::make('user', 'user', UserRepository::class),
)
];
}
Make sure that the column is fully qualified (include the table name).
The request could look like:
GET: /api/restify/posts?sort=-users.name
This will return all posts, sorted descending by users name.
As you may notice we have typed twice the users.name
(on the array key, and as argument in the setColumn
method). As soon as you use the fully qualified key name, you can avoid the setColumn
call, since the column will be injected automatically based on the sorts
key.
Sort using closure
If you have a quick sort method, you can use a closure to sort your data:
// PostRepository
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
public static function sorts(): array
{
return [
'users.name' => function(RestifyRequest $request, $query, $direction) {
// custom sort
}
];
}
Invokable Custom Sort Classes
Alongside the already provided sorting mechanisms, you can also use an invokable class. This provides you with a flexible way to create your own custom sort logic using classes.
Basic Usage
Such classes should implement the __invoke
method, which will be called during sorting. Here's an example:
class NaturalSort {
public function __invoke(RestifyRequest $request, Builder $query, string $order, string $column): void
{
$query->orderBy($column, $order);
}
};
You can then use it in your Repository's sorts
method like this:
public static function sorts(): array
{
return [
'name' => app(NaturalSort::class),
];
}
However, for even more convenience, you can also directly specify the invokable class name as a string:
PostRepository::$sort = [
'name' => NaturalSort::class,
];
Built-in Natural Sort Filter
For those not looking to write their own sort filters, binaryk/laravel-restify
already provides a built-in natural sort filter. This allows you to quickly sort fields in a natural order without additional implementations:
use Binaryk\LaravelRestify\Filters\Sorts\NaturalSortFilter;
PostRepository::$sort = [
'name' => NaturalSortFilter::class,
];
Using the NaturalSortFilter
class, you can effortlessly apply natural sorting to your repository fields.
Get available sorts
You can use the following request to get sortable attributes for a repository:
/api/restify/posts/filters?only=sortables
To get all filters, you can use /api/restify/posts/filters?only=sortables,matches,searchables
.