• Время чтения ~2 мин
  • 16.03.2023

Недавно я столкнулся с уникальным подходом к загрузке маршрутов в приложения Laravel, и я хотел поделиться этим с вами. Он позволяет создавать классы регистраторов маршрутов, в которых вы регистрируете свои маршруты. Я увидел это в пакете, который в настоящее время разрабатывается Ollie Read, и он привлек мое внимание как чистый и захватывающий способ регистрации маршрутов.

Изменения, необходимые для стандартного приложения Laravel, относительно просты. Мы вносим несколько изменений в поставщика услуг маршрутизации и удаляем веб-файлы маршрутов и файлы маршрутов API. Первое, что мы делаем, это создаем новую черту/беспокойство, которое мы можем добавить к нашему app/Providers/RouteServiceProvider призванному MapRouteRegistrars. Добавьте следующий код к этому новому признаку/проблеме.

declare(strict_types=1);

namespace App\Routing\Concerns;

use App\Routing\Contracts\RouteRegistrar;
use Illuminate\Contracts\Routing\Registrar;
use RuntimeException;

trait MapRouteRegistrars
{
    protected function mapRoutes(Registrar $router, array $registrars): void
    {
        foreach ($registrars as $registrar) {
            if (! class_exists($registrar) || ! is_subclass_of($registrar, RouteRegistrar::class)) {
                throw new RuntimeException(sprintf(
                    'Cannot map routes \'%s\', it is not a valid routes class',
                    $registrar
                ));
            }
            (new $registrar)->map($router);
        }
    }
}

Как вы можете видеть, нам также необходимо создать интерфейс / контракт для использования и обеспечить его реализацию всеми нашими регистраторами. Создайте это в разделе app/Routing/Contracts/RouteRegistrar и добавьте следующий код.

declare(strict_types=1);

namespace App\Routing\Contracts;

use Illuminate\Contracts\Routing\Registrar;

interface RouteRegistrar
{
    public function map(Registrar $registrar): void;
}

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

declare(strict_types=1);

namespace App\Providers;

use App\Routing\Concerns\MapsRouteRegistrars;
use Illuminate\Contracts\Routing\Registrar;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    use MapsRouteRegistrars;

    protected array $registrars = [];

    public function boot(): void
    {
        $this->routes(function (Registrar $router) {
            $this->mapRoutes($router, $this->registrars);
        });
    }
}

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

Теперь, когда наше приложение готово к использованию регистраторов маршрутов вместо файлов маршрутов, давайте создадим приложение по умолчанию для нашего приложения. Этот подход будет исключительно хорошо работать в управляемом доменом дизайне или модульной системе, позволяя каждому домену или модулю регистрировать свои маршруты. В этом примере мы сделаем это простым, чтобы вы могли понять подход. Создайте нового регистратора маршрутов app/Routing/Registrars/DefaultRegistrar.php и добавьте следующий код.

declare(strict_types=1);

namespace App\Routing\Registrars;

use App\Routing\Contracts\RouteRegistrar;

class DefaultRegistrar implements RouteRegistrar
{
    public function map(Registrar $registrar): void
    {
        $registrar->view('/', 'welcome');
    }
}

Теперь, когда наш регистратор по умолчанию создан, мы можем зарегистрировать его в нашем поставщике услуг маршрутизации, обеспечив его загрузку.

declare(strict_types=1);

namespace App\Providers;

use App\Routing\Concerns\MapsRouteRegistrars;
use App\Routing\Registrars\DefaultRegistrar;
use Illuminate\Contracts\Routing\Registrar;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    use MapsRouteRegistrars;

    protected array $registrars = [
        DefaultRegistrar::class,
    ];
    public function boot(): void
    {
        $this->routes(function (Registrar $router) {
            $this->mapRoutes($router, $this->registrars);
        });
    }
}

Теперь, если вы посещаете /, вы будете загружены welcome видом, а это значит, что все подключено правильно. Я могу представить себе отличный способ, которым я мог бы использовать это в своем приложении, где у меня есть статические маркетинговые маршруты, маршруты блогов, маршруты администраторов и многое другое. В качестве примера я бы предположил, что поставщик услуг маршрутизации выглядит следующим образом:

declare(strict_types=1);

namespace App\Providers;

use App\Routing\Concerns\MapsRouteRegistrars;
use App\Routing\Registrars\AdminRegistrar;
use App\Routing\Registrars\BlogRegistrar;
use App\Routing\Registrars\MarketingRegistrar;
use Illuminate\Contracts\Routing\Registrar;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    use MapsRouteRegistrars;

    protected array $registrars = [
        MarketingRegistrar::class, // Marketing Routes
        BlogRegistrar::class, // Blog Routes
        AdminRegistrar::class, // Admin Routes
    ];
    public function boot(): void
    {
        $this->routes(function (Registrar $router) {
            $this->mapRoutes($router, $this->registrars);
        });
    }
}

Разделение наших маршрутов таким образом - отличный способ перейти от стандартного файла маршрутов PHP к системе маршрутизации на основе классов, позволяющей лучше инкапсуляцию с вашим приложением или доменом.

Какие еще способы помочь вам управлять растущим приложением? Особенно с точки зрения маршрутизации, они могут стать немного непослушными через некоторое время. Сообщите нам об этом в Твиттере.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297