Declarar as rotas do Laravel com classes route registrar

Declarar as rotas do Laravel com classes route registrar

Neste artigo explico-te como declarar as tuas rotas de forma limpa, passando pela criação de uma classe Route Registrers onde registas as rotas. É uma maneira simples e arrumada de as declarar.

As alterações a fazer na tua aplicação Laravel são relativamente simples. Mexemos um pouco no service provider das rotas e apagamos os ficheiros de rotas web e API. A primeira coisa que fazemos é criar um novo trait/concern que podemos acrescentar ao nosso app/Providers/RouteServiceProvider, chamado MapRouteRegistrers. Acrescenta o código seguinte a esse novo 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 podes ver, temos também de criar uma interface/contrato para usar e garantir que todos os nossos Registrers a implementam.

Cria-a em App/Routing/Contracts/RouteRegistrer e acrescenta o código seguinte.

php
namespace App\Routing\Contracts;

use Illuminate\Contracts\Routing\Registrer;

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

Agora que o trait e a interface estão no lugar, podemos olhar para as alterações a fazer no service provider de routing por omissão.

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);
		});
	}
}

No código acima vês que acrescentámos uma nova propriedade ao nosso service provider de rotas. É nessa propriedade que os registrers de rotas da aplicação são registados e carregados no método de arranque.

Agora que a aplicação está pronta a usar registrers de rotas em vez de ficheiros de rotas, vamos criar um por omissão. Esta abordagem funcionaria excecionalmente bem num sistema modular ou num desenho orientado ao domínio, deixando cada domínio ou módulo registar as suas próprias rotas. Neste exemplo ficamos pelo simples, para que percebas a abordagem. Cria um novo registrer de rotas em app/Routing/Registrers/DefaultRegistrer.php e acrescenta o código seguinte.

php
namespace App\Routing\Registrers;

use App\Routing\Contracts\RouteRegistrer;

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

Com o nosso registrer por omissão criado, podemos registá-lo no Route Service Provider, garantindo que é carregado.

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);
		});
	}
}

Agora, se visitares « / », vais receber a vista « welcome », o que significa que está tudo bem ligado. No meu exemplo tenho rotas estáticas de marketing, de blog, de administração, 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, // Rotas de marketing
		BlogRegistrer::class, // Rotas do blog
		AdminRegistrer::class, // Rotas de administração
	];

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

Dividir as rotas desta maneira é uma excelente forma de passar de um ficheiro de rotas PHP normal para um sistema de routing baseado em classes, o que permite um melhor encapsulamento dentro da tua aplicação ou do teu domínio.

LaravelPHP

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.