Laravel: Aprende a organizar las rutas de tu proyecto
Tiempo de lectura: 3.41 minutos
Desde la versión 5.5 de Laravel, tenemos 4 archivos de rutas: api.php
, channels.php
, console.php
y web.php
.
Estos archivos nos permiten organizar nuestras rutas según el propósito que tienen.
- En
web.php
definimos las rutas de nuestra aplicación web (aquellas que consultan nuestros usuarios desde el navegador). - En
api.php
podemos declarar las rutas de nuestra o nuestras APIs. - En
console.php
han de estar nuestros comandos (sí, podemos declarar nuestros propiosartisan commands
por si aún no lo sabes). - Y
channels.php
nos permite definir canales de comunicación en tiempo real.
Cómo funcionan estos archivos de rutas
¿Cómo es posible que Laravel nos permita definir rutas desde distintos archivos?
Parece complicado, pero en realidad es muy sencillo.
Ve a RouteServiceProvider.php
(este archivo se encuentra en App\Providers
).
Este Service Provider se encarga de registrar todas las rutas de nuestro proyecto.
Aquí encontraremos un método map
. Éste método llama a otros 2 métodos (mapWebRoutes
y mapApiRoutes
), que se encuentran en la misma clase.
Y sorpresa:
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
Nos encontramos con algo muy similar a lo que solemos ver en los archivos de rutas.
- El método
mapWebRoutes
define un grupo de rutas. Les asocia el middlewareweb
y el namespace$this->namespace
, que es un atributo de la clase (cuyo valor por defecto esApp\Http\Controllers
, pero como vemos, es algo que podemos cambiar). Finalmente, lee las rutas que están declaradas enroutes/web.php
(y así quedan comprendidas en el grupo). - El método
mapApiRoutes
de igual manera define un grupo de rutas. La diferencia es que define un prefijoapi
y así mismo un middleware distinto, que esapi
en esta ocasión. El namespace es el mismo, pero las rutas que conforman el grupo son leídas desderoutes/api.php
.
Ahora todo tiene sentido, ¿verdad?
¿Necesitamos organizar más nuestras rutas?
Depende.
Si estamos trabajando sobre un proyecto pequeño, la organización actual podría ser suficiente.
Pero si estos archivos comienzan a crecer mucho, podemos organizar las rutas como creamos conveniente.
¿Cómo mejorar la organización de rutas?
Veamos un ejemplo de cómo podemos organizar nuestras rutas en carpetas.
Vamos a organizar nuestras rutas web. Pero ciertamente puedes seguir la misma idea para organizar tus rutas de API, comandos o canales.
Supongamos que tenemos muchas rutas definidas, y que están destinadas:
- Para administradores (gestionar datos y parámetros generales)
- Para usuarios (publicar una pregunta, editar perfil, seguir un curso)
- Para invitados (páginas públicas, como contacto, artículos)
Entonces, a fin de organizar mejor nuestras rutas, podemos cambiar la estructura por defecto:
Por esta otra estructura:
Es decir, estamos desplazando las rutas declaradas en web.php
a 3 archivos distintos, según los roles de nuestra aplicación (admin, user y guest).
Como repito, esta es sólo una propuesta.
Si la aplicación que estás desarrollando es muy grande, puedes seguir un orden distinto.
Por ejemplo, si tienes un proyecto Laravel que gestiona múltiples módulos o aplicaciones internas (como un blog, foro, cursos), puedes seguir esta otra propuesta:
Inclusive podrías tener carpetas dentro de carpetas.
Pero ojo. Tampoco lo pienses mucho. La idea es ganar un mayor orden, no a costa de quedarnos estancados.
¿Y cómo se hace?
Una vez que hayamos decidido la estructura que queremos seguir, simplemente debemos cargar todos los archivos de ruta desde nuestro RouteServiceProvider
.
Podemos modificar el método map
y llamar desde aquí nuevos métodos.
Pero como este método llama a mapWebRoutes
, y ahora nos estamos enfocando en rutas web
, ¿qué tal si llamamos desde este método a otros 3 métodos?
Es decir, vamos a reemplazar esto:
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
Para que quede de esta manera:
protected function mapWebRoutes()
{
$this->mapWebAdminRoutes();
$this->mapWebUserRoutes();
$this->mapWebPublicRoutes();
/* si recién estamos clasificando nuestras rutas, aquí
podemos seguir cargando web.php hasta que ya no se necesite */
}
Así podemos cargar cada archivo que hemos creado como un grupo de rutas independiente (con su propio middleware
, namespace
y prefix
, según sea requerido).
Por ejemplo (puedes seguir la siguiente idea y definir mapWebUserRoutes
y mapWebPublicRoutes
):
protected $namespaceAdmin = 'App\Http\Controllers\Admin';
// ..
protected function mapWebAdminRoutes()
{
Route::middleware('web')
->namespace($this->namespaceAdmin)
->prefix('admin')
->group(base_path('routes/web/admin.php'));
}
Pero si no necesitas personalizar tanto a este nivel (y prefieres ser más específico al interior de cada archivo), también podemos hacer lo siguiente, para simplementar cargar archivos de ruta, bajo las mismas condiciones:
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(function () {
require base_path('routes/web.php');
require base_path('routes/web/admin.php');
require base_path('routes/web/user.php');
require base_path('routes/web/guest.php');
});
}
Todos los caminos conducen a Roma
Si bien podemos cargar rutas desde RouteServiceProvider
, no es el único camino posible.
Al final, todo lo que escribimos es código PHP.
Incluso si usamos require
o include
desde un archivo de rutas para cargar otros, también funcionaría.
Conclusión
Laravel define una clase RouteServiceProvider
, y la sitúa en App\Providers
.
Desde aquí podemos organizar y cargar las rutas de nuestra aplicación.
La lógica que hace todo esto posible forma parte del framework, y se encuentra por tanto en la carpeta vendor.
Pero Laravel expone ante nosotros todo aquello que pueda resultar de nuestro interés, a fin de que sea sencillo personalizar.
Cuéntame en los comentarios qué te ha parecido este tutorial, de qué forma piensas organizar las rutas de tu proyecto, y así mismo, en qué consiste la app que estás desarrollando en estos momentos.