oxy.su / dev.extreme
dev-extreme server laravel
Requires
- php: ^8.3
- illuminate/support: ^11.0
README
Пакет адаптирован под POSTGRES
Установка
composer require oxy.su/dev.extreme
Использование
в файлах App/Builders/{component}/{Component}Builder
<?php
namespace App\Builders\{Component}s;
use Oxy\DevExtreme\SortAndFilterPipelineAction;
use Illuminate\Database\Eloquent\Builder;
use App\Models\{Component};
class {Component}Builder extends SortAndFilterPipelineAction
{
/**
* Получить builder модели {Component}.
*
* @return Builder
*/
public function query(): Builder
{
return {Component}::query();
}
}
Пример использования в контроллере
<?php
...
public function index({Component}Builder $builder): {Component}Collection
{
// Возвращается query со всеми установленными фильрами.
${Component}Query = $builder->handle();
return {Component}Collection::make(${Component}Query);
}
Пример использования в Коллекции в ресурсах
<?php
namespace App\Http\Resources\{Component}s;
use Oxy\DevExtreme\Resources\PaginationResource;
class {Component}Collection extends PaginationResource
{
public $collects = {Component}Resource::class;
}
Пример использования builder
<?php
namespace App\Builders\Users;
use App\Models\Role;
use App\Models\User;
use Oxy\DevExtreme\SortAndFilterPipelineAction;
use Illuminate\Support\Facades\DB;
class UserBuilder extends SortAndFilterPipelineAction
{
public function __construct(
private Request $request,
private Company $company
) {}
/**
* Получить выборку пользователей.
*/
public function query()
{
// необходимо вернуть основной query
return DB::table('users')
->where('company_id', $this->company->id)
->with($request->input('slugRole'), fn ($query, $slugRole) => $query
->whereHas('role', fn ($query) => $query->where('slug', $slugRole))
);
}
/**
* Основная таблица
* ps: необходимо указать если используется Illuminate\Database\Query\Builder,
* при использовании Illuminate\Database\Eloquent\Builder автоматически берет из модели
* - метод не обязателен
*
* @return string
*/
public function getTable(): string
{
return with(new User())->getTable();
}
/**
* Сопоставление полей к таблицам
* ps: если поле переданное в параметре filter не указано в данном массиве, то sql сопоставляется с основной таблицей
* - метод не обязателен
*
* @return array
*/
public function matching(): array
{
return [
// поле => таблица
'slug' => with(new Role())->getTable(),
];
}
}
или
<?php
namespace App\Builders\Users;
use App\Models\User;
use Oxy\DevExtreme\SortAndFilterPipelineAction;
use Illuminate\Database\Eloquent\Builder;
class UserBuilder extends SortAndFilterPipelineAction
{
/**
* Получить выборку пользователей.
*/
public function query(): Builder
{
return User::query();
}
}
в контроллере
/**
* Получить выборку пользователей.
*
* @param UserBuilder $builder
*
* @return UserCollection
*/
public function index(UserBuilder $builder): UserCollection
{
// Возвращается query со всеми установленными фильрами.
$userQuery = $builder->handle();
return UserCollection::make($userQuery);
}
или
/**
* Получить выборку пользователей.
*
* @param Request $request
* @param Company $comapnay
*
* @return UserCollection
*/
public function index(Request $request, Company $comapnay): UserCollection
{
$builder = new UserBuilder($request, $comapnay);
// Возвращается query со всеми установленными фильрами.
$userQuery = $builder->handle();
return UserCollection::make($userQuery);
}
Параметры get запроса
- take - integer - Количество элементов для отображения
- skip - integer - Количество элементов которое нужно пропустить
isLoadingAll - boolean - отобразить все элементы, при этом игнорируются take и skip
filter - array - массив условий выборки данных
- sort - array - сортировка выборки
- relation - array - массив отношений которые нужно дотобразить в выборке. Доступные отнашения отображаются в данных ответа.
примеры:
1)
GET {API_URL_DOMEN}/section-endpoints?take=10&skip=100
{
take: 10,
skip: 100
}
2)
GET {API_URL_DOMEN}/section-endpoints?take=10&filter[]=description&filter[]=contains&filter[]=океан&sort[selector]=title
{
take: 10,
filter[]: description
filter[]: contains
filter[]: океан
sort[selector]: title
}
описание sort
sort это массив из элементов:- selector (поле по котору производится сортировка) и необезательного второго параметра
который может быть order с указанием типа: asc, desc, rand или asc=true или desc=true
...sort[selector]=title&sort[desc]=true
...sort[selector]=title&sort[asc]=true
...sort[selector]=title&sort[order]=desc
{
sort: {
selector: "title", // поле сортировки
desc: true // тип сортировки
}
}
{
sort: {
selector: "title", // поле сортировки
asc: true // тип сортировки
}
}
{
sort: {
selector: "title", // поле сортировки
order: "desc" // тип сортировки
}
}
либо sort можно указать много мерным масивом
...sort[0][selector]=title&sort[0][order]=desc&sort[1][selector]=code
{
sort: [
{
selector: "title", // поле сортировки
order: "desc" // тип сортировки
},
{
selector: "code" // поле сортировки
// тип сортировки по умолчанию asc
}
]
}
описание filter
filter это массив из элементов по 3 параметра
[
"description", // поле фильтрации
"contains", // Функция фильтрации
"океан" // значение фильтрации
]
Список функций фильтрации:
математические:
"=" - равенство
"<=" - больше или равно
">=" - меньше или равно
"!=" или "<>" - не равно
">" - больше
"<" - меньше
строковые:
"contains" - содержит
"startswith" - начинается на
"endswith" - заканчивается на
"notcontains" - не содержит
Массив элементов можно вложить в группу при необходимости двойного условия
[
[
"description", // поле фильтрации
"contains", // Функция фильтрации
"океан" // значение фильтрации
],
"and", // функция совмешения блоков
[
"description", // поле фильтрации
"notcontains", // Функция фильтрации
"атлантический" // значение фильтрации
]
]
в виде запроса: ...filter[0][]=description&filter[0][]=contains&filter[0][]=океан&filter[1]=and&filter[2][]=description&filter[2][]=notcontains&filter[2][]=атлантический
в таком случаи появляется параметр функции совмещения который может быть and
, or
, xor
и находится
между блоками условий, всегда на нечетных позициях.
также можно составить более сложное условие выборки сделав сложенный блок
[
[
[
"description", // поле фильтрации
"contains", // Функция фильтрации
"океан" // значение фильтрации
],
"or", // функция совмешения блоков
[
"description", // поле фильтрации
"contains", // Функция фильтрации
"море" // значение фильтрации
],
],
"and", // функция совмешения блоков
[
"description", // поле фильтрации
"notcontains", // Функция фильтрации
"атлантический" // значение фильтрации
]
]
в виде запроса: ...filter[0][0][]=description&filter[0][0][]=contains&filter[0][0][]=океан&filter[0][1]=or&filter[0][2][]=description&filter[0][2][]=contains&filter[0][2][]=море&filter[1]=and&filter[2][]=description&filter[2][]=notcontains&filter[2][]=атлантический
Работа с отношениями (relations)
Новый ключ relation[]
В пакет добавлен новый ключ relation[]
, который позволяет указать отношения,
которые необходимо загрузить вместе с основным запросом.
Отображение доступных отношений В ответе API также отображаются все доступные отношения модели. Это позволяет клиентам узнать, какие отношения можно запросить.
Использование relation в запросе Вы можете передать массив отношений, которые нужно загрузить вместе с основным запросом. Например:
...&relation[]=user&relation[]=employeeRole
Эти отношения будут автоматически подключены в ресурсе. Но для отображения в ресурсе необходимо их вывести.
Пример использования в ресурсе:
public function toArray(Request $request): array
{
/** @var Employee $resource */
$resource = $this->resource;
return [
'id' => $resource->id,
...
'user' => UserResource::make($this->whenLoaded('user')),
'company' => CompanyResource::make($this->whenLoaded('company')),
'employeeRole' => EmployeeRoleResource::make($this->whenLoaded('employeeRole')),
];
}
Использование отношений типа belongsTo в фильтрации и сортировке Если отношение является типом belongsTo, его можно использовать в фильтрации и сортировке без дополнительной подготовки. Например, если модель Employee имеет отношение public function user() { return $this->belongsTo(User::class); }, вы можете использовать его в фильтре так:
filter[
"user.surname", // отнашение через точку имя поя в отнашении
"startswith", // фнкция фильтрации - «начинается с»
"Иван" // значение сортировки
]
Это позволяет фильтровать сотрудников по фамилии пользователя, которая начинается с "Иван".
Заключение: Laravel Dev Extreme предоставляет гибкий и мощный инструмент для создания API с продвинутыми возможностями фильтрации, сортировки и пагинации. Используя этот пакет, вы можете легко реализовать сложную логику выборки данных, оставаясь в рамках привычной архитектуры Laravel.
Не забудьте адаптировать примеры под свои конкретные модели и требования проекта. При возникновении вопросов или проблем обращайтесь к документации пакета или создавайте issues в репозитории проекта.