Ostatnio natknąłem się na unikalne podejście do ładowania tras do aplikacji Laravel i chciałem się tym z wami podzielić. Umożliwia tworzenie klas rejestratorów tras, w których rejestrujesz swoje trasy. Widziałem to w pakiecie opracowywanym obecnie przez Ollie Reada i przykuło moją uwagę jako czysty i ekscytujący sposób rejestrowania tras.
Zmiany wymagane w standardowej aplikacji Laravel są stosunkowo proste. Wprowadzamy kilka zmian w usłudze Route Service Provider i usuwamy pliki tras internetowych i API. Pierwszą rzeczą, którą robimy, jest stworzenie nowej cechy / troski, którą możemy dodać do naszego app/Providers/RouteServiceProvider
powołania MapRouteRegistrars
. Dodaj następujący kod do tej nowej cechy/problemu.
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);
}
}
}
Jak widać, musimy również stworzyć interfejs/umowę do wykorzystania i upewnić się, że wszyscy nasi rejestratorzy go wdrażają. Utwórz to w obszarze app/Routing/Contracts/RouteRegistrar
i dodaj następujący kod.
declare(strict_types=1);
namespace App\Routing\Contracts;
use Illuminate\Contracts\Routing\Registrar;
interface RouteRegistrar
{
public function map(Registrar $registrar): void;
}
Teraz, gdy mamy już tę cechę i interfejs, możemy przyjrzeć się zmianom, które musimy wprowadzić w domyślnym dostawcy usług trasy.
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);
});
}
}
Z powyższego kodu widać, że dodaliśmy nową właściwość do naszego dostawcy usług trasy. Ta właściwość jest miejscem, w którym rejestratorzy tras aplikacji są rejestrowani i ładowani wewnątrz metody rozruchu.
Teraz, gdy nasza aplikacja jest gotowa do korzystania z rejestratorów tras zamiast plików tras, utwórzmy domyślną aplikację dla naszej aplikacji. Takie podejście sprawdziłoby się wyjątkowo dobrze w projektowaniu opartym na domenie lub systemie modułowym - umożliwiając każdej domenie lub modułowi rejestrowanie swoich tras. W tym przykładzie zachowamy prostotę, abyś mógł zrozumieć podejście. Utwórz nowego rejestratora marszruty i app/Routing/Registrars/DefaultRegistrar.php
dodaj następujący kod.
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');
}
}
Teraz, gdy nasz domyślny rejestrator jest tworzony, możemy zarejestrować go w naszym dostawcy usług trasy, upewniając się, że jest załadowany.
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);
});
}
}
Teraz, jeśli odwiedzisz /
, zostaniesz załadowany welcome
widokiem, co oznacza, że wszystko jest poprawnie podłączone. Mogę sobie wyobrazić świetny sposób, w jaki mógłbym to wykorzystać w mojej aplikacji, w której mam statyczne ścieżki marketingowe, trasy blogów, ścieżki administracyjne i wiele innych. Na przykład wyobrażam sobie, że dostawca usług tras wygląda następująco:
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);
});
}
}
Dzielenie naszych tras w ten sposób to świetny sposób na przejście ze standardowego pliku tras PHP do systemu routingu opartego na klasach, który pozwala na lepszą hermetyzację z aplikacją lub domeną.
Jakie inne sposoby zostały znalezione, aby pomóc Ci zarządzać rozwijającą się aplikacją? Zwłaszcza z punktu widzenia routingu po pewnym czasie mogą stać się trochę niesforne. Daj nam znać na Twitterze.