Routes en Laravel 5.7
En este post voy a explicar cómo funcionan las rutas en Laravel 5.7. Podría ser casi una traducción de la documentación oficial, pero lo voy a explicar a mi modo.
Por cierto, ya había hablado sobre las rutas en Laravel hace algún tiempo: Cuidado con las rutas en Laravel.
Ahora explicaré las rutas en forma de tutorial.
Recomendados
Mira cómo comenzar a programar con Laravel en este post. Si quieres un enrutador o router sin Laravel, mira lo que escribí sobre Phroute.
Funcionamiento de las rutas
Las rutas son llamadas dependiendo de la URL que el usuario requiera y los archivos que se encargan de ellas están en la carpeta routes. Dentro de dicha carpeta tenemos por defecto 4 archivos:
- api.php: rutas que tienen el prefijo api, funcionan para cuando armamos una API que cualquiera puede consumir.
- channels.php: canales que sirven para propagar mensajes, esto lo veremos en otro post
- console.php: rutas pero ahora desde la consola o terminal, no desde el navegador
- web.php: seguramente lo que todos queremos, las rutas que son llamadas desde el navegador web.
En este post me centraré en explicar las rutas web, los verbos HTTP, expresiones regulares y otras cosas.
Las rutas de la web
A simple vista se ve que el archivo web.php solamente maneja las rutas, pero internamente pasa todas las peticiones por algunos middlewares (que veremos más tarde) de seguridad y lógica.
Todas nuestras rutas definidas aquí pasarán por una validación del token CSRF y tendrán todas las características para leer o escribir en la sesión, sin que nosotros escribamos nada de código.
Verbos HTTP
Los métodos o verbos HTTP podrían llevarse un post completo, pero en resumen hay “verbos” que indican lo que se desea hacer. Entre ellos encontramos:
- get: normalmente para obtener recursos o valores
- put: verbo usado para editar
- post: cuando vamos a agregar algo nuevo, normalmente un insert si lo vemos desde las bases de datos. Con este método se envían los formularios.
- delete: cuando vamos a eliminar algo.
Nota: la diferencia entre get y post es que con get los datos viajan en la url (si alguien ve las urls que visitas y por ellas se manda la contraseña, podría averiguarla) y con post los mismos viajan en el cuerpo de la petición. Si combinas post con https tienes una app segura.
¿Y por qué tantos verbos si nos bastaría con GET y POST?
Al tener varios verbos, tus rutas se expresan mejor. Por ejemplo, una administración de usuarios quedaría así:
- POST usuario: insertar usuario
- PUT usuario: actualizar usuario
- GET usuario: obtener un usuario
- DELETE usuario: eliminar un usuario
En cambio, si solamente existiera GET y POST:
- POST usuario: insertar usuario
- POST actualizarUsuario: actualizar usuario
- GET usuario: obtener usuario
- POST eliminarUsuario: eliminar un usuario
Al tener varios verbos, expresamos las cosas de mejor manera. Por cierto, esos no son todos los que existen ni todos los que soporta Laravel, la lista completa es:
GET, POST, PUT, PATCH, DELETE, OPTIONS.
Escuchando verbos HTTP desde las rutas de Laravel
Ahora que ya sabemos los verbos veamos cómo escuchar cuando un usuario llama a un verbo desde Laravel. Por cierto, la ruta base es:
ruta_del_proyecto/public/
Las rutas se escriben relativas a esta ruta. Veamos cómo se define una dentro de web.php:
<?php
Route::get("/", function(){
# Lo que se regrese aquí se muestra en el navegador
return "Solicitaste la ruta /";
});
Como primer argumento pasamos la cadena de la ruta que será resuelta, y como segundo argumento una función que será ejecutada dependiendo de esa ruta. Ya veremos más adelante que el segundo argumento podría ser otra cosa en lugar de una función.
Eso es lo básico que necesitas saber al trabajar con las rutas de Laravel.
Parámetros en las rutas
Las rutas sin parámetros no sirven de mucho; ya que siempre los necesitaremos para cualquier aplicación web. Por ejemplo, si hacemos una página en donde se ve el perfil de los usuarios, algunas rutas podrían ser:
- usuario/pedro
- usuario/luis
- usuario/maggie
Si analizamos bien, esa ruta comienza con usuario y de ahí tiene un argumento. Entonces podríamos escucharla así:
<?php
Route::get("/usuario/{nombre}", function($nombre){
return "Quieres ver el perfil de $nombre";
});
De esta manera, el argumento se pasa dentro de la URL y también a la función.
Parámetros opcionales en las rutas
Supongamos que tenemos una aplicación web en donde tenemos a empleados o trabajadores de una empresa.
¿Todos los empleados tienen un puesto, verdad? bueno, ahora digamos que tenemos que filtrarlos por puesto opcionalmente, y si no se proporciona puesto, se devuelven todos.
La solución a esto son los parámetros opcionales, que pueden ser o no mandados. Eso sí, dentro de la función debemos definir un valor por defecto para ese argumento:
<?php
Route::get("/empleados/{puesto?}", function ($puesto = null) {
if ($puesto === null) {
# Devolvemos todos los empleados
return "Quieres obtener a todos los empleados";
} else {
# Devolver por puesto
return "Quieres obtener según el puesto: $puesto";
}
});
Podríamos darle otro valor por defecto en lugar de null, esto depende de lo que estemos haciendo.
Rutas más largas
No estamos limitados (excepto por el navegador y tiempo de parseo) a escribir rutas cortas o dejar los parámetros al final. Una ruta larga podría definirse así:
<?php
Route::get("/ventas/{anio}/departamento/{departamento?}", function ($anio, $departamento = "todos") {
return "Quieres obtener las ventas del año $anio y del departamento (opcional) $departamento";
});
Así es como nos damos cuenta de que no importa la posición de los argumentos ni la longitud de la ruta. En ese caso primero recibimos el año como argumento obligatorio y luego el departamento como argumento opcional que por defecto es todos.
Expresiones regulares en las rutas
A veces queremos responder a rutas pero que cumplan con cierto criterio. Por ejemplo, si obtenemos usuarios por id, el mismo debe ser numérico y no debería responderse a la ruta usuario/hola porque hola no es un número.
Justo aquí vienen a salvarnos las expresiones regulares, que aunque son otro tema, podemos entender fácilmente las cosas más básicas. Veamos unos ejemplos:
<?php
Route::get("/usuario/{id}", function($id){
return "Solamente respondo si el id tiene 1 o más dígitos numéricos";
})->where("id", '[0-9]+');
#Nota: el slug es el enlace amigable, por ejemplo: crud-de-mysql. Una ruta
# se vería así: articulo/2019/crud-de-mysql
Route::get("/articulo/{anio}/{slug}", function($anio, $slug){
return "Quieres ver un artículo del año $anio con el slug $slug";
})->where(
# Pasar un arreglo con las expresiones que deben cumplir
[
"anio" => '[0-9]{4}', # Año de 4 dígitos exactos (no funcionará después del año 9999)
"slug" => '[A-Za-z0-9-_]+', # Conformado por letras mayúsculas o minúsculas, guiones bajos _ o normales - y números
]
);
En el primer ejemplo se valida que sea un dígito del 0 al 9 y que aparezca más de una vez. En el segundo se validan dos cosas: el año y el slug. Aquí tenemos una petición válida:
Pero aquí no ponemos un año válido y por lo tanto vamos a la página de not found:
De esta forma podemos combinar las rutas de Laravel con algunas expresiones regulares para crear robustas y expresivas estructuras.
Es importante notar que cuando validamos únicamente un parámetro llamamos a where
con el nombre del parámetro y su expresión regular.
En cambio, cuando son más parámetros, le pasamos un arreglo en donde las claves son el nombre del parámetro y los valores la expresión regular.
Llamar a controladores desde las rutas
Los controladores se quedan para otro post, pero por ahora basta con saber que podemos llamar a métodos de controladores desde las rutas, sin crear una función y esas cosas. Veamos un ejemplo:
<?php
# Cuando se envía el formulario y se debe guardar la canción
Route::post("/agregar", "CancionesController@agregarCancion");
Dentro del código vamos a llamar al método agregarCancion
del controlador CancionesController
.
Ahora el segundo argumento ya no es una función, sino una cadena. La forma que tiene es NombreDelControlador@MétodoDelControlador
.
Dentro del controlador igualmente podemos recibir datos de la URL o datos de formulario y cosas de esas.
Renderizar vistas con las rutas de Laravel
Al igual que los controladores, las vistas son otro tema, pero se ligan a las rutas. Normalmente renderizaremos algunas vistas dependiendo de la URL que nos soliciten.
Por ejemplo, veamos cómo renderizar algunas páginas de una landing page como dicen los chicos de hoy:
<?php
Route::view("/contacto", "contacto");
Route::view("/acerca-de", "acercaDe", ["anio" => date("Y")]);
Route::view("/quienes-somos", "quienesSomos");
Route::view("/servicios", "servicios");
No te preocupes por las vistas, basta con que sepas que el primer argumento es la URL (así como en los ejemplos anteriores) y el segundo es el nombre de la vista que se va a renderizar.
Cuando visitan la página de acerca de le pasamos un tercer argumento que es un arreglo de datos que solamente lleva el año, esto es para demostrar que podemos pasar datos a las vistas (podrían ser miles de datos pero eso es tema de las vistas) y mostrarlos.
Esto de las vistas igualmente puede hacerse desde un controlador; se recomienda poner aquí las vistas que son simples y no llevan (o llevan pocos) datos, para evitar la complejidad.
Redirecciones de rutas
Si queremos redireccionar, podríamos hacer esto:
<?php
Route::get("/pagina-antigua", function(){
return redirect("pagina-nueva");
});
Pero Laravel proporciona una mejor manera:
<?php
Route::redirect("/pagina-antigua", "pagina-nueva");
Al final se logra lo mismo pero de una forma más expresiva.
Poner nombres a rutas
Terminemos este tutorial (porque ya se hizo largo) exponiendo una cosa importantísima: poner nombres a las rutas.
Cuando estamos en un proyecto pequeño el nombre de las rutas no importa mucho, pero conforme avanzamos o cambiamos cosas esto se vuelve útil.
Por ejemplo, siguiendo con la landing page, seguramente hicimos un menú de navegación con un enlace que decía “Acerca de” y poníamos el enlace “/acerca-de” que apuntaba a la ruta.
El problema viene cuando queremos cambiar la ruta, pues tendríamos que cambiar los enlaces. Sé que en este caso solamente es uno, pero recomiendo siempre nombrar a las rutas así:
<?php
Route::view("/acerca-de", "acercaDe")->name("acercaDe");
Luego, en las vistas (que veremos más adelante) generamos el enlace llamando a una función y pasándole el nombre de la ruta:
{{ route('acercaDe') }}
De esta manera, si en el futuro ya no es /acerca-de sino /sobre-nosotros solamente iremos al archivo de rutas y cambiaríamos esa parte; todos los enlaces serían generados con la nueva URL sin importar el número de los mismos.
Conclusión
Esta es la continuación de Comenzando a programar en Laravel. También puedes ver otras cosas que he escrito sobre este framework de PHP.
Como referencia dejo el enlace a la documentación oficial.
Pingback: Flash data en Laravel para mostrar avisos - Parzibyte's blog
Pingback: Rutas en Laravel parte 2: prefijos, fallback, límite de tasa y formularios - Parzibyte's blog