У матеріалі розбирається підхід Gautier Deleglise у пакеті lomkit/laravel-rest-api версії 3.0. Автор пакета повністю переробив внутрішню реалізацію, але зберіг ключову ідею: одна ресурсна клас перетворює Eloquent модель на повноцінний REST API.
1. Typed fields — одна декларація керує валідацією, фільтрами і відповідями
У гілці 2.x ресурс мав список колонок. У 3.0 ресурс описує поля як типізовані об'єкти: Text, Integer, Number, Date, Enum, Json тощо. Це змінює спосіб побудови API: вся логіка «знає» тип кожного поля.
Приклад ресурсної конфігурації, яку описує автор:
public function fields(): array
{
return [
ID::make('id'),
Text::make('title')->rules('max:80')->creationRules('required'),
Integer::make('seats')->rules('min:0'),
Enum::make('status', ShowStatus::class)->offered([ShowStatus::Planned, ShowStatus::OnSale]),
Date::make('starts_on')->creationRules('required'),
];
}
Ключова ідея: один опис поля використовується для кількох задач одразу.
- Фільтри поважають тип — для кожного типу доступні лише релевантні оператори. Якщо клієнт надсилає несумісний оператор, API повертає
422. Це прибирає велику частину ручних перевірок. - Валідація записів — записи перевіряються за правилами, прив'язаними до поля (
rules(),creationRules()). Помилки «прив'язані» до конкретного ключа, наприкладmutate.0.attributes.seats, що полегшує обробку помилок на фронтенді. - Типізовані відповіді — сервер повертає значення у «правильних» типах: числа як числа, порожній JSON як
{}, а неnullчи порожній рядок. Це зменшує кількість умов у клієнтському коді. - Керування допустимими значеннями enum —
Enum::offered()обмежує, які константи клієнт може записати. Наприклад, статус «withdrawn» може залишатися доступним у старих рядках (читання і фільтрація), але його не можна встановити заново у нових записях. Це корисно для «застарілих, але ще присутніх» станів.
Практичний наслідок: замість того щоб дублювати список полів і правила по контролерах, формується єдина точка правди в ресурсі. Для великих проєктів це особливо помітно на підтримці.
2. OpenAPI документація через Scramble замість вбудованого генератора
У 2.x пакет мав власний генератор документації. У версії 3.0 його видалили і інтегрувалися зі стороннім інструментом Scramble. Логіка з опису полів перекладається в OpenAPI схеми.
Після встановлення Scramble ендпоінт /docs/api описує кожен ресурс і кожен маршрут:
- структуру тіла запиту, сформовану з typed fields ресурсу;
- валідаційні правила для кожного поля;
- приклади запитів;
- опис помилок у відповідях.
У тестовому наборі самого пакета приклади запитів із документації фактично відправляються до API, а відповіді звіряються з описом OpenAPI. Якщо реалізація і документація розходяться, падає тест. Це підхід «документація як контракт», який знижує ризик «мертвих» чи застарілих описів.
3. Метрики без контролерів — Value, Trend, Partition, Progress і Table
У 3.0 з'явився окремий шар для побудови метрик над ресурсом. Розробник описує метрику на ресурсі, і вона автоматично отримує маршрут без написання контролера.
Приклад, наведений в оригіналі, — розподіл шоу за статусами через метрику Partition:
class ShowsByStatus extends Partition
{
public function calculate(Builder $query): PartitionResult
{
return $this->count($query, 'status');
}
}
Відповідь ендпоінта містить ключ кожної групи, її напис (label) і значення (count):
{"data": {"type": "partition", "parts": [{"key": "planned", "label": "planned", "value": 2}, {"key": "sold_out", "label": "sold_out", "value": 1}], "other": null}}
Автор пакета виділяє кілька типів метрик:
Value— агрегати на кшталт лічильника, суми, середнього, медіани, перцентилів;Trend— значення по часових відрізках (наприклад, кількість записів по днях);Partition— розбивка за категоріями, як у прикладі зі статусами;Progress— значення поточного прогресу відносно цілі;Table— табличні метрики.
Особливості, на які звертає увагу автор:
- Діапазони дат і часові зони — метрики враховують діапазони часу та часовий пояс, що дозволяє будувати, наприклад, тижневі чи місячні тренди для певної таймзони.
- Порівняння з попереднім періодом — можна отримати дельту відносно попереднього часового інтервалу (наприклад, зміна кількості бронювань «тиждень до тижня»).
- Кеш результатів — результати метрик кешуються, щоб не рахувати важкі агрегації на кожен запит.
- Поважання політик і периметра — метрика рахує тільки ті рядки, які користувач має право бачити. Додатково клієнт може передавати ті самі фільтри, що й для пошуку, щоб ще звузити вибірку.
Такий підхід зручний для дашбордів: замість окремих контролерів та агрегацій поверх Eloquent, вся логіка метрик оформлена як класи, пов'язані з конкретним ресурсом.
4. Підтвердження для дій і масових змін через 428 і підписаний токен
У версії 3.0 з'явився вбудований механізм підтверджень для потенційно небезпечних операцій. Його можна ввімкнути для:
- action;
- mutate;
- destroy;
- restore;
- force destroy.
Автор наводить приклад підтвердження для масового видалення шоу і пов'язаних квитків:
public function destroyConfirmation(Collection $models): ?Confirmation
{
return Confirmation::make("Delete {$models->count()} shows and their tickets?");
}
Поводження ендпоінта у такому випадку:
- перше звернення повертає статус
428(Precondition Required), текст повідомлення і підписаний токен; - клієнт має повторити той самий запит, додавши токен, — тоді операція виконується;
- сесія не використовується, додатковий ендпоінт для підтвердження не потрібен.
Це підходить, наприклад, для інтерфейсів, де користувач має явно підтвердити масове видалення або незворотні дії, не будуючи власну складну схему з тимчасовими станами чи сесіями.
5. Політики, транзакції і пошук — як змінилася «важка» логіка
Крім typed fields, документації і метрик, автор пакета виділяє низку змін у поведінці безпосередньо API.
5.1. Політики і периметр доступу
- Політики виконуються для кожного ресурсу, до якого доходить запит, і для кожного рядка, який записується, ще до першого запису.
perimeterQuery()дозволяє обмежити кожен ресурс у рамках «тенанта» або «команди» на всіх рівнях пошуку. Це форма глобального, але керованого multi-tenant фільтра.
5.2. Комплексні операції запису в одній транзакції
Пакет у 3.0 дозволяє в одному запиті:
- створювати батьківські й дочірні записи;
- оновлювати існуючі;
- attach/sync для зв'язків;
- видаляти дочірні рядки.
Усе це виконується в одній транзакції. Через блок response клієнт може отримати назад створені або змінені рядки, а ресурси, для яких увімкнено versioned(), будуть повертати 409, якщо рядок змінився після того, як клієнт його прочитав. Це варіант оптимістичної блокування на рівні REST.
5.3. Actions з різними моделями транзакцій
Actions у 3.0 можуть виконуватися з різною «гранулярністю» транзакцій:
- одна транзакція на весь запуск;
- одна транзакція на «chunk»;
- окрема транзакція для кожного рядка.
Є підтримка чергування chunk'ів і batch'ів з репортингом прогресу, що спрощує оргнанізацію довгих операцій, на кшталт масового перерахунку чи міграції даних.
5.4. Повторне використання пошуку за межами HTTP
Rest::search() дозволяє «програти» збережений пошуковий запит поза HTTP контекстом. Таким чином, job або експорт можуть користуватися тими ж фільтрами, політиками і правилами, що і HTTP API, без повторного опису логіки.
5.5. Пошук по тексту і інтеграції із Scout
Для текстового пошуку пакет підтримує кілька варіантів:
LIKEна рівні SQL;- full-text індекси MySQL, MariaDB та PostgreSQL;
- Meilisearch, Typesense, Algolia через Laravel Scout.
Це дає змогу налаштовувати однакове REST API поверх різних бэкендів пошуку, залежно від можливостей інфраструктури.
5.6. Локалізація повідомлень
Усі повідомлення, що потрапляють до клієнта, у пакеті постачаються англійською та французькою мовами і підлаштовуються під locale запиту.
6. Автогенерація ресурсів і контроль у CI
Для пришвидшення старту проєкту автор пакета додав дві корисні Artisan-команди:
php artisan rest:quick-start— читає структуру таблиць і генерує ресурсні класи, контролери, стартові політики і маршрути;php artisan rest:check— підходить для CI, виявляє, наприклад, відсутню політику або perimeter для ресурсу.
Крім того, пакет включає skill для Laravel Boost, завдяки чому AI асистент (описаний в оригінальному матеріалі) може генерувати ресурси в тому форматі, якого очікує пакет.
7. Вимоги до середовища і оновлення до 3.0
На відміну від гілки 2.x, Laravel Rest Api 3.0 має підвищені вимоги:
- PHP версії 8.3+;
- Laravel версії 13.30+.
Якщо застосунок працює на Laravel 12, автор рекомендує залишатися на гілці 2.x.
Встановлення 3.0 виглядає так:
Оскільки у версії 3.0 є breaking changes по всьому пакету, команда пакета підготувала детальний гайд з оновлення: UPGRADE.md. Там розглянуті зміни по розділах, тому при міграції з 2.x варто орієнтуватися саме на нього, а не на окремі приклади з огляду.
Повні деталі релізу можна знайти у release notes, а також у офіційній документації https://laravel-rest-api.lomkit.com та репозиторії GitHub https://github.com/Lomkit/laravel-rest-api.
Джерело: Eric L. Barnes — Laravel News