Исследование middleware в Laravel 11

Источник: «Exploring Middleware in Laravel 11»
Мне кажется, что это изменение в Laravel 11 потребует гораздо больше неявных знаний о встроенном middleware. Имеет ли это значение? Скорее всего, нет. Но это изменение увеличивает кривую обучения.

Выход Laravel 11 намечен на "первый квартал" 2024 года, это может произойти уже в следующем месяце.

Я начинаю новый проект, и поскольку до релиза осталось совсем немного времени, я решил взглянуть на то, что изменится в новом крупном релизе. Я помню, как 6 месяцев назад прочитал в Laravel News статью, что Http Kernel уходит, и не придал этому особого значения.

Когда я создал проект с помощью laravel new project --dev, я был очень удивлён тем, насколько уменьшился размер проекта. Очень удивительно было увидеть пустую папку config (вы можете опубликовать файлы конфигурации с помощью php artisan config:publish)!

И, конечно, никакого Http Kernel не существует. Итак… как же добавить или изменить middleware? До Laravel 11 Http Kernel (находится в app/Http/Kernel.php) был местом, где находилась вся конфигурация для middleware. Также до Laravel 11 вы обычно не трогали bootstrap/app.php. Однако в новой версии это уже не так.

Честно говоря, для меня, как пользователя Laravel с версии 4.2, это довольно серьёзная смена парадигмы. Вместо легко читаемого файла Kernel.php появилось гораздо больше неявных знаний, необходимых для добавления middleware.

Новая отправная точка для bootstrap/app.php выглядит следующим образом:

return Application::configure()
->withProviders()
->withRouting(
web: __DIR__.'/../routes/web.php',
// api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
// channels: __DIR__.'/../routes/channels.php',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();

В этом посте я просто исследую промежуточное ПО, но, как вы видите, это совсем другой подход, чем тот, который существовал раньше. Я сидел и ломал голову: "Как мне настроить собственное middleware? Как изменить настройки по умолчанию?" Чтобы выяснить это, мне пришлось изучить класс Illuminate\Foundation\Configuration\Middleware.

Вызов Application::configure() возвращает экземпляр Illuminate\Foundation\Configuration\ApplicationBuilder, в котором затем вызываются различные функции, withProviders(), withRouting() и withMiddleware(). Функция withMiddleware() принимает вызываемый объект.

Используя шаблон, мы можем добавлять новые псевдонимы middleware, вызывая alias():

function (Middleware $middleware) {
$middleware->alias([
'some_key' => \App\Http\Middleware\MyMiddleware::class,
]);
}

После добавления some_key мы можем назначить его отдельным маршрутам и группам маршрутов. Если мы хотим добавлять middleware в каждый запрос, мы можем использовать функции append() или prepend() для добавления глобального middleware.

function (Middleware $middleware) {
// Используя строку
$middleware->append(\App\Http\Middleware\MyMiddleware::class);

// Или добавить несколько
$middleware->append([
\App\Http\Middleware\MyMiddleware::class,
\App\Http\Middleware\MyOtherMiddleware::class,
]);
}

Мы можем удалить middleware, находящееся там по умолчанию, вызвав функцию remove().

function (Middleware $middleware) {
// ИСпользуя строку
$middleware->remove(\Illuminate\Http\Middleware\ValidatePostSize::class);

// Оли удалить несколько middleware использующихся по умолчанию
$middleware->remove([
\Illuminate\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
]);
}

Мы можем добавлять или удалять middleware в определённые группы, например, в веб-группу, используя функции appendToGroup()/prependToGroup() и removeFromGroup().

function (Middleware $middleware) {
$middleware->appendToGroup('web', \App\Http\Middleware\MyMiddleware::class);
}

Если/когда этот файл bootstrap/app.php станет немного беспорядочным (а я представляю, что так и будет), мы можем навести порядок, перенеся всё это в вызываемый класс.

Я создал класс в app/Http под названием AppMiddleware.php. Поскольку старые привычки умирают, вы можете назвать его Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Configuration\Middleware;

class AppMiddleware
{
public function __invoke(Middleware $middleware)
{
$middleware->appendToGroup('web', \App\Http\Middleware\MyMiddleware::class);
}
}

Теперь в файле bootstrap/app.php замените замыкание на новый экземпляр нашего вызываемого класса.

return Application::configure()
->withProviders()
->withRouting(
web: __DIR__.'/../routes/web.php',
// api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
// channels: __DIR__.'/../routes/channels.php',
)
->withMiddleware(new \App\Http\AppMiddleware())
->withExceptions(function (Exceptions $exceptions) {
//

Как и всё новое, перемены даются тяжело. В связи с этими переменами меня мучает один вопрос. У нас есть всё те же инструменты и возможности, но понять, как всем этим управлять, немного сложнее, по крайней мере поначалу.

Мне кажется, что это изменение потребует гораздо больше неявных знаний о встроенном middleware. Имеет ли это значение? Скорее всего, нет. Но в некоторых случаях вам может понадобиться удалить или заменить middleware по умолчанию. Это потребует от вас знания того, что есть по умолчанию. Не только в глобальном middleware, но и в группах и middleware с псевдонимами. Мне кажется, что это изменение увеличивает кривую обучения. Даже я забываю, что там есть по умолчанию или в каких псевдонимах находится, и регулярно ссылаюсь на файл app/Http/Kernel.php.

Я задаюсь вопросом, стоит ли это того, чтобы отказаться от многословности и уменьшить размер файла?

Что вы думаете об этом новом изменении?

Дополнительные материалы

Предыдущая Статья

Именовать вещи всё ещё сложно?

Следующая Статья

Виртуальные колонки БД в миграциях Laravel и MySQL