¿Muchas rutas en tu proyecto Laravel? Organízalas!

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 propios artisan 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:

<?php
  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 middleware web y el namespace $this->namespace, que es un atributo de la clase (cuyo valor por defecto es App\Http\Controllers, pero como vemos, es algo que podemos cambiar). Finalmente, lee las rutas que están declaradas en routes/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 prefijo api y así mismo un middleware distinto, que es api en esta ocasión. El namespace es el mismo, pero las rutas que conforman el grupo son leídas desde routes/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.

Organizar nuestras rutas Laravel

¿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: Estructura de rutas en Laravel

Por esta otra estructura: Alternativa según roles

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:

Alternativa según módulos

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:

<?php
  protected function mapWebRoutes()
  {
      Route::middleware('web')
           ->namespace($this->namespace)
           ->group(base_path('routes/web.php'));
  }

Para que quede de esta manera:

<?php
  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):

<?php
  // ...
  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:

<?php
  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.

laravel

Cursos recomendados

Curso de Laravel 5.5

Aprende Laravel

Aprende Laravel 5.5 desde cero y desarrolla aplicaciones web reales, en tiempo récord, de la mano de Laravel.

Ver más
Curso de Laravel y OAuth 2 (Login con redes sociales)

Laravel y OAuth2

Veamos cómo implementar un login mediante redes sociales! Aprende y aplica esto sobre cualquier proyecto Laravel.

Ver más
Curso de Laravel, Vue.js y Pusher

Aprende Vue.js

Desarrollemos un Messenger! Aprende sobre Channels, Queues, Vuex, JWT, Sesiones, BootstrapVue y mucho más.

Ver más
Logo de Programación y más

¿Tienes alguna duda?

Si algo no te quedó claro o tienes alguna sugerencia, escribe un comentario aquí debajo.

Además recuerda compartir el post si te resultó de ayuda. Gracias!

Antes que te vayas

Inscríbete en nuestro curso gratuito de Laravel