Как стать автором
Обновить

Автоматические имена роутов Laravel

Время на прочтение4 мин
Количество просмотров4.4K

Данная статья не описывает стандартные реализации нейминга маршрутов будь то name(), resource() либо apiResource. Информацию по ним Вы можете прочитать в официальной документации здесь, здесь, здесь и здесь.

В статье описывается расширяющий коробочный функционал программный продукт.

Часто разработчики при создании проектов пренебрегают именованием маршрутов по разным причинам, например, когда они вообще не обращаются к ним используя функцию route(). Это обусловлено архитектурой приложения и в этом нет ничего зазорного, но есть и такие проекты, где имена маршрутов являются неотъемлемой частью проекта и случается так, что не ко всем роутам указываются имена. Об этом мы и поговорим.

В таких проектах можно запросто встретить следующий вид имён:

URI

Route Name

GET /api/short/{key}

short_link

POST /api/review

POST /api/phone/confirm

phone.confirm

POST /api/crm/orders

api.crm.

GET /api/crm/orders/{id}

api.crm.

Как мы видим, в коде проекта используется обращение всего к двум маршрутам из данного списка, или не используется - этот факт не доказан, пока мы сами не найдём использование.

Так или иначе, данные имена как минимум вводят в заблуждение об использовании и имеют некрасивый и непрезентабельный вид, а способствует этому простая лень.

Исправить ситуацию поможет пакет dragon-code/laravel-route-names, позволяющий в автоматическом режиме формировать имена маршрутов на основании uri.

Например, вышеприведённые адреса получат следующие имена:

URI

Route Name

GET /api/short/{key}

api.short.show

POST /api/review

api.review.store

POST /api/phone/confirm

api.phone.confirm

POST /api/crm/orders

api.crm.orders.store

GET /api/crm/orders/{id}

api.crm.orders.show

Как мы видим, имена стали осмысленные и автоматически заполненные.

Ещё одной особенностью данного пакета является то, что он совместим со всеми программными решениями по расширению списка маршрутов, например, dragon-code/extended-routes.

Установка и настройка

Основная проблема работы с маршрутами такого уровня во фреймворке Laravel заключается в том, что они инициализируются при старте приложения, и если пытаться заменить корневой Kernel через сервис-провайдеры, то это плохо скажется на производительности, так как сперва будут инициализированы стандартные маршруты, и только после этого будут перезаписаны обработанные. В итоге получим что маршруты инициализируются два раза, чего нам совсем не нужно.

Поэтому мы подменим его на старте приложения, таким образом, сохраним функциональность.

Итак, для начала нужно установить зависимость через Composer:

composer require dragon-code/laravel-route-names

Затем в файле bootstrap/app.php приложения необходимо заменить Illuminate\Foundation\Application на DragonCode\LaravelRouteNames\Application.

И всё 🙂

Да, это правда всё. Отныне все маршруты приложения будут автоматически формировать имена в красивом, понятном и очевидном виде.

app('router')
    ->name('pages.')
    ->prefix('pages')
    ->group(function () {
        app('router')->get('/', [Controller::class, 'index']);
        app('router')->post('/', [Controller::class, 'store']);
        app('router')->get('{page}', [Controller::class, 'show']);
        app('router')->delete('{page}', [Controller::class, 'destroy']);
    });

До:

GET     /pages         pages.
POST    /pages         pages.
GET     /pages/{page}  pages.
DELETE  /pages/{page}  pages.

После:

GET     /pages         pages.index
POST    /pages         pages.store
GET     /pages/{page}  pages.show
DELETE  /pages/{page}  pages.destroy

Также не забывайте на продакшене использовать кэширование роутов, вызывая команду php artisan route:cache или, ещё лучше, php artisan optimize. Они позволят закэшировать результаты и не прибегать к динамическому формированию не только маршрутов, но и остальных данных в системе. Подробнее про оптимизацию деплоя можно почитать в официальной документации Laravel.

А в скором времени будет поддержка динамических имён в плагине Laravel Idea. Разработка уже ведётся 😎

Коллизии

Пакет также решает одну из важных проблем - коллизии при использовании имён маршрутов. Кто не в курсе, коллизии маршрутов - это одинаковые имена роутов при разных конечных URL. То есть, в коде подразумевается обращение к одному URL, а, по факту, будет сформировано совершенно к другому.

Например, в коробочном функционале можно легко достичь коллизии следующими роутами:

app('router')
    ->middleware('api')
    ->prefix('admin')
    ->group(function () {
        app('router')->resource('books', BookController::class);
        // ...
    });

app('router')
    ->middleware('web')
    ->group(function () {
        app('router')->resource('books', BookController::class);
        // ...
    });

Коробочный функционал сгенерирует следующие данные:

GET     /admin/books              books.index
GET     /admin/books/{book}       books.show
GET     /admin/books/{book}/edit  books.edit
DELETE  /admin/books/{book}       books.destroy

GET     /books                    books.index
GET     /books/{book}             books.show
GET     /books/{book}/edit        books.edit
DELETE  /books/{book}             books.destroy

Применяя пакетное решение:

GET     /admin/books              admin.books.index
GET     /admin/books/{book}       admin.books.show
GET     /admin/books/{book}/edit  admin.books.edit
DELETE  /admin/books/{book}       admin.books.destroy

GET     /books                    books.index
GET     /books/{book}             books.show
GET     /books/{book}/edit        books.edit
DELETE  /books/{book}             books.destroy

Да, Вы можете использовать коробочный функционал на ресурсах, например:

app('router')->resource('admin.books', BookController::class);
app('router')->resource('books', BookController::class);

Но в этом случае изначально в архитектуру приложения должно быть заложено использование подобного рода маршрутов без использования "обычных" вроде get(), post() и так далее, иначе в них теряется смысл.

Описанный в посте пакет как раз решает именно эти проблемы.

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 7: ↑6 и ↓1+5
Комментарии41

Публикации

Истории

Работа

PHP программист
147 вакансий

Ближайшие события