Изучение мидлварей в Laravel 11

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

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

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

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

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

Новый начальный файл 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();

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

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

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

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

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

function (Middleware $middleware) {
    // Using a string
    $middleware->append(\App\Http\Middleware\MyMiddleware::class);

    // Or adding multiple
    $middleware->append([
        \App\Http\Middleware\MyMiddleware::class,
        \App\Http\Middleware\MyOtherMiddleware::class,
    ]);
}

Мы можем удалить дефолтные мидлвари, вызвав функцию remove():

function (Middleware $middleware) {
    // Using a string
    $middleware->remove(\Illuminate\Http\Middleware\ValidatePostSize::class);

    // Or removing multiple default middleware
    $middleware->remove([
        \Illuminate\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
    ]);
}

Мы можем добавлять или удалять мидлвари в определённых группах, например, в web, используя функции 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()) // here
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

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

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

Я сомневаюсь стоит ли оно того. А что Вы думаете об этом?

@Helldar
09.01.2024 13:12 UTC
Первоисточник

Комментарии

@AleksandrTm
09.01.2024 13:28 UTC
+4

" Это потребует от Вас знания того, что есть по-умолчанию. "

Интересно, не будет ли расширен список artisan команд в таком случае

artisan middleware:list

@Helldar
10.01.2024 08:07 UTC
0

Скорее всего будет, т.к. ни для кого не секрет что Тейлор идёт на поводу общества и когда народ массово начнёт его спрашивать о том как посмотреть список, он добавит эту команду.

Также как если попытаться её добавить до того как народ обратит внимание, ответит дефолтным сообщением "пиши пакет" и закроет PR ?

@firdavsBEK
10.01.2024 19:21 UTC
+1

Это по моему типа слияние люмена и ларавеля, то есть если хотим апи, тогда не нужные мидлвари не будут загружаться, то есть web часть не будет работать

@2medic
01.02.2024 06:28 UTC
0

«Пока изучаешь один фреймворк, выходит три новых ©»

Переход на 11-ю версию Laravel вызовет сильную когнитивную нагрузку. А с учётом того, что в самом PHP существует тенденция на отказ от магических методов, на которых в Laravel многое завязано, то Laravel при любом раскладе ждут серьёзные перемены.

Я начинаю новый проект

Может быть есть смысл посмотреть в сторону Symfony? Стабильные релизы, хороший LTS: 4 года поддержки, в минорных версиях совместимость не ломается.

@Helldar
01.02.2024 07:14 UTC
+1

Laravel давно перешёл на семантическое версионирование и между минорами совместимость не ломается.

Касательно LTS, когда-то оно было, но не каждый "мажор". Последние LTS - 5.1 и 5.5. Эти версии поддерживались в течение двух лет с момента релиза в плане багов и улучшений и 3 года для фиксов безопасности в то время как остальные - один год на баги и улучшения и 2 года на безопасность.

Но, начиная с версии 6.0, когда внедрили человеческое версионирование, от Тейлор отказался от LTS из-за того что вместо траты сил на разработку нового, ему приходилось тратить время и силы на поддержание трупа. Да и при выходе новых версий нет проблем апгрейднуться по подробному гайду, а если проект такой что апгрейд дороже выйдет, никто не запрещает продолжать его использовать, ведь, если на тот момент он работает, значит баги фрейма либо не использует, либо уже вставлены костыли для их решения.

Касательно стабильности, здесь тоже всё в порядке. Плановый выпуск - каждый вторник минор и каждый февраль мажор. Начали появляться сообщения что на следующей неделе будет релиз 11-й версии несмотря на то, что официально на сайте указан 1-й квартал.

Что же по симфе, а смысл менять шило на мыло? Лара под капотом имеет компоненты симфы в том числе. Также очень много плюшек, сахара и чёрной магии. Да, с магией здесь зачастую перебор, мягко говоря, но работает. Стану ли лично я переходить на симфони? Нет.