Declarar las rutas de Laravel con clases route registrar

Declarar las rutas de Laravel con clases route registrar

En este artículo te explico cómo declarar tus rutas de forma limpia creando una clase Route Registrers en la que las registras. Es una manera clara y sencilla de declararlas.

Los cambios que hay que hacer en tu aplicación Laravel son bastante sencillos. Tocamos un poco el proveedor de servicios de rutas y eliminamos los archivos de rutas web y API. Lo primero es crear un nuevo trait/concern que podemos añadir a nuestro app/Providers/RouteServiceProvider, llamado MapRouteRegistrers. Añade el siguiente código a ese nuevo trait/concern.

php
namespace App\Routing\Concerns;

use App\Routing\Contracts\RouteRegistrer;
use Illuminate\Contracts\Routing\Registrer;
use RuntimeException;

trait MapRouteRegistrers
{
	protected function mapRoutes(Registrer $router, array $registrers): void
	{
		foreach ($registrers as $registrer) {
			if (! class_exists($registrer) || ! is_subclass_of($registrer, RouteRegistrer::class)) {
				throw new RuntimeException(sprintf(
					'Cannot map routes \'%s\', it is not a valid routes class',
					$registrer
				));
			}

(new $registrer)->map($router);
		}
	}
}

Como puedes ver, también tenemos que crear una interfaz/contrato y asegurarnos de que todos nuestros Registrers la implementan.

Créala en App/Routing/Contracts/RouteRegistrer y añade el siguiente código.

php
namespace App\Routing\Contracts;

use Illuminate\Contracts\Routing\Registrer;

interface RouteRegistrer
{
	public function map(Registrer $registrer): void;
}

Ahora que el trait y la interfaz están en su sitio, podemos ver los cambios que hay que aplicar al proveedor de servicios de rutas por defecto.

php
namespace App\Providers;

use App\Routing\Concerns\MapsRouteRegistrers;
use Illuminate\Contracts\Routing\Registrer;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
	use MapsRouteRegistrers;

protected array $registrers = [];

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

En el código anterior puedes ver que hemos añadido una nueva propiedad a nuestro proveedor de servicios de rutas. En esa propiedad se registran los registrars de rutas de la aplicación, que se cargan en el método de arranque.

Ahora que nuestra aplicación está lista para usar registrars de rutas en lugar de archivos de rutas, vamos a crear uno por defecto. Este enfoque funciona especialmente bien en un sistema modular o en un diseño orientado a dominios, porque permite que cada dominio o módulo registre sus propias rutas. Para este ejemplo vamos a mantenerlo simple, para que entiendas bien el planteamiento. Crea un nuevo registrar de rutas en app/Routing/Registrers/DefaultRegistrer.php y añade el siguiente código.

php
namespace App\Routing\Registrers;

use App\Routing\Contracts\RouteRegistrer;

class DefaultRegistrer implements RouteRegistrer
{
	public function map(Registrer $registrer): void
	{
		$registrer->view('/', 'welcome');
	}
}

Ahora que nuestro registrar por defecto está creado, podemos declararlo en nuestro Route Service Provider para asegurarnos de que se carga.

php
namespace App\Providers;

use App\Routing\Concerns\MapsRouteRegistrers;
use App\Routing\Registrers\DefaultRegistrer;
use Illuminate\Contracts\Routing\Registrer;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
	use MapsRouteRegistrers;

protected array $registrers = [
		DefaultRegistrer::class,
	];

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

Si ahora visitas «/», se cargará la vista «welcome», lo que significa que todo está bien conectado. En mi ejemplo tengo rutas estáticas de marketing, de blog, de administración, etc.:

php
namespace App\Providers;

use App\Routing\Concerns\MapsRouteRegistrers;
use App\Routing\Registrers\AdminRegistrer;
use App\Routing\Registrers\BlogRegistrer;
use App\Routing\Registrers\MarketingRegistrer;
use Illuminate\Contracts\Routing\Registrer;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
	use MapsRouteRegistrers;

protected array $registrers = [
		MarketingRegistrer::class, // Rutas de marketing
		BlogRegistrer::class, // Rutas del blog
		AdminRegistrer::class, // Rutas de administración
	];

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

Dividir las rutas de esta manera es una forma excelente de pasar de un archivo de rutas PHP estándar a un sistema de enrutamiento basado en clases, lo que permite una mejor encapsulación dentro de tu aplicación o de tu dominio.

LaravelPHP

Damien Flandrin Desarrollador web desde 2010, creador de Gekkode y de Email Impact. Cada artículo se prueba en un proyecto real antes de publicarse. Contacto
Newsletter

Las nuevas pruebas, tutoriales y proyectos, por correo.

Pruebas reproducibles, código versionado, resultados fechados. Nunca spam.