Dominar las rutas de Laravel
Publicado: 2022-12-12Cuando se trata del backend, los desarrolladores eventualmente encuentran rutas. Las rutas pueden considerarse la columna vertebral del backend, ya que cada solicitud que recibe el servidor se redirige a un controlador a través de una lista de enrutamiento que asigna solicitudes a controladores o acciones.
Laravel oculta muchos detalles de implementación para nosotros y viene con mucha azúcar sintáctica para ayudar a los desarrolladores nuevos y experimentados a desarrollar sus aplicaciones web.
Echemos un vistazo de cerca a cómo administrar rutas en Laravel.
Enrutamiento de backend y secuencias de comandos entre sitios en Laravel
En un servidor, existen rutas tanto públicas como privadas. Las rutas públicas pueden ser motivo de preocupación debido a la posibilidad de secuencias de comandos en sitios cruzados (XSS), un tipo de ataque de inyección que puede dejarlo a usted y a sus usuarios vulnerables a actores malintencionados.
El problema es que se puede redirigir a un usuario desde una ruta que no requiere un token de sesión a una que sí lo requiere, y seguirá teniendo acceso sin el token.
La forma más sencilla de resolver este problema es aplicar un nuevo encabezado HTTP, agregando "referente" a la ruta para mitigar este escenario:
'main' => [ 'path' => '/main', 'referrer' => 'required,refresh-empty', 'target' => Controller\DashboardController::class . '::mainAction' ]
Enrutamiento básico de Laravel
En Laravel, las rutas permiten a los usuarios enrutar la solicitud adecuada al controlador deseado. La ruta de Laravel más básica acepta un identificador uniforme de activos (su ruta de ruta) y un cierre que puede ser tanto una función como una clase.
En Laravel, las rutas se crean dentro de los archivos web.php y api.php . Laravel viene con dos rutas por defecto: una para la WEB y otra para la API.
Estas rutas residen en la carpeta route/ , pero se cargan en Providers/RouteServiceProvider.php .
En lugar de hacer esto, podemos cargar las rutas directamente dentro de RouteServiceProvider.php , omitiendo la carpeta route/ por completo.
Redirecciones
Cuando definimos una ruta, normalmente querremos redirigir al usuario que accede a ella, y las razones de esto varían mucho. Puede ser porque es una ruta obsoleta y hemos cambiado el backend o el servidor, o puede ser porque queremos instalar la autenticación de dos factores (2FA), etc.
Laravel tiene una manera fácil de hacer esto. Gracias a la simplicidad del marco, podemos usar el método de redirección en la fachada de la ruta, que acepta la ruta de entrada y la ruta a la que se redirigirá.
Opcionalmente, podemos dar el código de estado para la redirección como tercer parámetro. El método permanentRedirect
hará lo mismo que el método redirect
, excepto que siempre devolverá un código de estado 301:
// Simple redirect Route::redirect("/class", "/myClass"); // Redirect with custom status Route::redirect("/home", "/office", 305); // Route redirect with 301 status code Route::permanentRedirect("/home", "office");
Dentro de las rutas de redirección, tenemos prohibido usar las palabras clave "destino" y "estado" como parámetros, ya que están reservados por Laravel.
// Illegal to use Route::redirect("/home", "/office/{status}");
Puntos de vista
Las vistas son el . archivos blade.php que usamos para renderizar la interfaz de nuestra aplicación Laravel. Utiliza el motor de plantillas blade y es la forma predeterminada de crear una aplicación de pila completa utilizando solo Laravel.
Si queremos que nuestra ruta devuelva una vista, simplemente podemos usar el método de vista en la fachada de la ruta. Acepta un parámetro de ruta, un nombre de vista y una matriz opcional de valores para pasar a la vista.
// When the user accesses my-domain.com/homepage // the homepage.blade.php file will be rendered Route::view("/homepage", "homepage");
Supongamos que nuestra vista quiere decir "Hola, {name}
" pasando una matriz opcional con ese parámetro. Podemos hacer exactamente eso con el siguiente código (si se requiere el parámetro faltante en la vista, la solicitud fallará y generará un error):
Route::view('/homepage', 'homepage', ['name' => "Kinsta"]);
Lista de rutas
A medida que su aplicación crece en tamaño, también lo hará la cantidad de solicitudes que deben enrutarse. Y con un gran volumen de información puede surgir una gran confusión.
Aquí es donde el artisan route:list command
puede ayudarnos. Proporciona una descripción general de todas las rutas definidas en la aplicación, sus middlewares y controladores.
php artisan route:list
Mostrará una lista de todas las rutas sin los middlewares. Para esto, tenemos que usar el indicador -v
:
php artisan route:list -v
En una situación en la que puede estar utilizando un diseño controlado por dominio donde sus rutas tienen nombres específicos en sus rutas, puede utilizar las capacidades de filtrado de este comando de la siguiente manera:
php artisan route:list –path=api/account
Esto mostrará solo las rutas que comienzan con api/account .
Por otro lado, podemos indicarle a Laravel que excluya o incluya rutas definidas por terceros usando las opciones –except-vendor
o –only-vendor
.
Parámetros de ruta
En ocasiones, es posible que deba capturar segmentos del URI con la ruta, como una ID de usuario o un token. Podemos hacer esto definiendo un parámetro de ruta, que siempre está encerrado entre llaves ( {}
) y solo debe constar de caracteres alfabéticos.
Si nuestras rutas tienen dependencias dentro de sus devoluciones de llamada, el contenedor de servicios de Laravel las inyectará automáticamente:
use Illuminate\Http\Request; use Controllers/DashboardController; Route::post('/dashboard/{id}, function (Request $request, string $id) { return 'User:' . $id; } Route::get('/dashboard/{id}, DashboardController.php);
Parámetros requeridos
Los parámetros requeridos de Laravel son parámetros en las rutas que no podemos omitir cuando hacemos una llamada. De lo contrario, se arrojará un error:
Route::post("/gdpr/{userId}", GetGdprDataController.php");
Ahora dentro de GetGdprDataController.php tendremos acceso directo al parámetro $userId .
public function __invoke(int $userId) { // Use the userId that we received… }
Una ruta puede tomar cualquier número de parámetros. Se inyectan en las devoluciones de llamada/controladores de ruta según el orden en que se enumeran:
// api.php Route::post('/gdpr/{userId}/{userName}/{userAge}', GetGdprDataController.php); // GetGdprDataController.php public function __invoke(int $userId, string $userName, int $userAge) { // Use the parameters… }
Parámetros opcionales
En una situación en la que queremos hacer algo en una ruta cuando solo está presente un parámetro y nada más, todo sin afectar a toda la aplicación, podemos agregar un parámetro opcional. Estos parámetros opcionales se indican con el ?
adjunto a ellos:
Route::get('/user/{age?}', function (int $age = null) { if (!$age) Log::info("User doesn't have age set"); else Log::info("User's age is " . $age); } Route::get('/user/{name?}', function (int $name = "John Doe") { Log::info("User's name is " . $name); }
Comodín de ruta
Laravel nos proporciona una manera de filtrar el aspecto que deberían tener nuestros parámetros opcionales o requeridos.
Digamos que queremos una cadena de ID de usuario. Podemos validarlo así en el nivel de ruta usando el método where
.
El método where
acepta el nombre del parámetro y la regla regex que se aplicará en la validación. Por defecto, toma el primer parámetro, pero si tenemos muchos, podemos pasar una matriz con el nombre del parámetro como clave y la regla como valor, y Laravel los analizará todos por nosotros:
Route::get('/user/{age}', function (int $age) { // }->where('age', '[0-9]+'); Route::get('/user/{age}', function (int $age) { // }->where('[0-9]+'); Route::get('/user/{age}/{name}', function (int $age, string $name) { // }->where(['age' => '[0-9]+', 'name' => '[az][Az]+');
Podemos llevar esto un paso más allá y aplicar la validación en todas las rutas de nuestra aplicación utilizando el método pattern
en la fachada de la Route
:
Route::pattern('id', '[0-9]+');
Esto validará cada parámetro id
con esta expresión regular. Y una vez que lo definamos, se aplicará automáticamente a todas las rutas que usen ese nombre de parámetro.
Como podemos ver, Laravel está usando el carácter /
como separador en la ruta. Si queremos usarlo en la ruta, debemos permitir explícitamente que sea parte de nuestro marcador de posición usando una expresión regular where
.
Route::get('/find/{query}', function ($query) { // })->where('query', , '.*');
El único inconveniente es que solo se admitirá en el último segmento de la ruta.
Rutas con nombre
Como sugiere el nombre, podemos nombrar rutas, lo que hace que sea conveniente generar URL o redirigir para rutas específicas.
Cómo crear rutas con nombre
El método de nombre encadenado en la fachada Route
proporciona una forma sencilla de crear una ruta con name
. El nombre de cada ruta debe ser único:
Route::get('/', function () { })->name("homepage");
Grupos de rutas
Los grupos de rutas le permiten compartir atributos de ruta como middlewares en una gran cantidad de rutas sin necesidad de volver a definirlos en todas y cada una de las rutas.
software intermedio
Asignar un middleware a todas las rutas que tenemos nos permite combinarlas en un grupo, primero usando el método group
. Una cosa a considerar es que los middlewares se ejecutan en el orden en que se aplican al grupo:
Route:middleware(['AuthMiddleware', 'SessionMiddleware'])->group(function () { Route::get('/', function() {} ); Route::post('/upload-picture', function () {} ); });
Controladores
Cuando un grupo utiliza el mismo controlador, podemos usar el método controller
para definir el controlador común para todas las rutas dentro de ese grupo. Ahora tenemos que especificar el método que llamará la ruta.
Route::controller(UserController::class)->group(function () { Route::get('/orders/{userId}', 'getOrders'); Route::post('/order/{id}', 'postOrder'); });
Enrutamiento de subdominio
Un nombre de subdominio es una pieza de información adicional agregada al comienzo del nombre de dominio de un sitio web. Esto permite que los sitios web separen y organicen su contenido para funciones específicas, como tiendas en línea, blogs, presentaciones, etc., del resto del sitio web.
Nuestras rutas se pueden usar para manejar el enrutamiento de subdominios. Podemos capturar el dominio y una parte del subdominio para usar en nuestro controlador y ruta. Con la ayuda del método domain
en la fachada Route
, podemos agrupar nuestras rutas bajo un solo dominio:
Route::domain('{store}.enterprise.com')->group(function() { Route::get('order/{id}', function (Account $account, string $id) { // Your Code } });
Prefijos y prefijos de nombres
Siempre que tengamos un grupo de rutas, en lugar de modificarlas una por una, podemos hacer uso de las utilidades extra que proporciona Laravel, como prefix
y name
en la fachada de la Route
.
El método prefix
se puede usar para prefijar cada ruta en el grupo con un URI dado, y el método name
se puede usar para prefijar cada nombre de ruta con una cadena dada.
Esto nos permite crear cosas nuevas como rutas de administración sin tener que modificar todos y cada uno de los nombres o prefijos para identificarlos:
Route::name('admin.")->group(function() { Route::prefix("admin")->group(function() { Route::get('/get')->name('get'); Route::put('/put')->name(put'); Route::post('/post')->name('post'); }); });
Ahora los URI para estas rutas serán admin/get
, admin/put
, admin/post
y los nombres admin.get
, admin.put
y admin.post
.
Almacenamiento en caché de ruta
Al implementar la aplicación en servidores de producción, un buen desarrollador de Laravel aprovechará el caché de rutas de Laravel.
¿Qué es el almacenamiento en caché de rutas?
El almacenamiento en caché de rutas reduce la cantidad de tiempo que lleva registrar todas las rutas de la aplicación.
Al ejecutar php artisan route:cache
se genera una instancia de Illuminate/Routing/RouteCollection
y, después de codificarse, la salida serializada se escribe en bootstrap/cache.routes.php
.
Ahora cualquier otra solicitud cargará este archivo de caché si existe. Por lo tanto, nuestra aplicación ya no tiene que analizar y convertir entradas del archivo de ruta en objetos Illuminate/Routing/Route
en Illuminate/Routing/RouteCollection
.
Por qué es importante utilizar el almacenamiento en caché de rutas
Al no utilizar la función de almacenamiento en caché de rutas que proporciona Laravel, su aplicación corre el riesgo de ejecutarse más lentamente de lo que podría ser, lo que a su vez podría disminuir las ventas, la retención de usuarios y la confianza en su marca.
Según la escala de su proyecto y la cantidad de rutas que haya, ejecutar un comando simple de almacenamiento en caché de rutas puede acelerar su aplicación entre un 130 % y un 500 %, una ganancia enorme casi sin esfuerzo.
Resumen
El enrutamiento es la columna vertebral del desarrollo de back-end. El marco de Laravel se destaca en esto al proporcionar una forma detallada de definir y administrar rutas.
De hecho, el desarrollo puede ser accesible para todos y ayudar a acelerar una aplicación solo en virtud de que está construida en Laravel.
¿Qué otros trucos y consejos has encontrado con respecto a las rutas de Laravel? ¡Infórmenos en la sección para comentarios!