Skip to content

3. Rutas (Routing) en Laravel

El sistema de rutas de Laravel es una parte fundamental del framework que permite definir cómo la aplicación responde a las solicitudes HTTP. Las rutas se definen en archivos ubicados en el directorio

routes/
, donde cada archivo corresponde a un tipo específico de ruta.

ArchivoDescripción
routes/web.php
Rutas para la interfaz web
routes/api.php
Rutas para la API
routes/console.php
Comandos de consola personalizados
routes/channels.php
Canales de broadcasting

Laravel proporciona métodos para definir rutas para todos los verbos HTTP comunes. Cada método acepta dos parámetros: la URI y una función callback o un controlador.

Las rutas GET se utilizan para solicitar datos del servidor sin modificarlos.

// En routes/web.php
use IlluminateSupportFacadesRoute;
Route::get('/usuarios', function () {
return 'Lista de usuarios';
});
// Usando un controlador
Route::get('/usuarios', [UsuarioController::class, 'index']);

Las rutas POST se utilizan para enviar datos al servidor, como al enviar un formulario.

Route::post('/usuarios', function () {
// Lógica para crear un nuevo usuario
return 'Usuario creado';
});
// Usando un controlador
Route::post('/usuarios', [UsuarioController::class, 'store']);

Las rutas PUT y PATCH se utilizan para actualizar recursos existentes.

Route::put('/usuarios/{id}', function ($id) {
// Lógica para actualizar un usuario
return 'Usuario ' . $id . ' actualizado';
});
Route::patch('/usuarios/{id}', [UsuarioController::class, 'update']);

Las rutas DELETE se utilizan para eliminar recursos.

Route::delete('/usuarios/{id}', function ($id) {
// Lógica para eliminar un usuario
return 'Usuario ' . $id . ' eliminado';
});
Route::delete('/usuarios/{id}', [UsuarioController::class, 'destroy']);

Si necesitas que una ruta responda a múltiples verbos HTTP, puedes usar el método

match
:

Route::match(['get', 'post'], '/usuarios/buscar', function () {
// Lógica para buscar usuarios
});
// O para todos los verbos HTTP
Route::any('/usuarios/acciones', function () {
// Responde a cualquier verbo HTTP
});
<form action="/usuarios/1" method="POST">
@csrf
@method('PUT')
<!-- Campos del formulario -->
<button type="submit">Actualizar</button>
</form>

Las rutas con parámetros permiten capturar segmentos de la URI para utilizarlos en tu aplicación. Estos parámetros se definen en la ruta utilizando llaves

{}
.

Los parámetros requeridos se definen con llaves y se pasan como argumentos a la función de callback o método del controlador.

Route::get('/usuarios/{id}', function ($id) {
return 'Usuario con ID: ' . $id;
});
// Múltiples parámetros
Route::get('/posts/{post}/comentarios/{comentario}', function ($postId, $comentarioId) {
return 'Post ' . $postId . ', comentario ' . $comentarioId;
});

Los parámetros opcionales se definen añadiendo un signo de interrogación

?
después del nombre del parámetro. Debes proporcionar un valor predeterminado para estos parámetros en la función.

Route::get('/usuarios/{nombre?}', function ($nombre = 'invitado') {
return 'Hola ' . $nombre;
});
// Con controlador
Route::get('/productos/{categoria?}', [ProductoController::class, 'index']);

Puedes restringir el formato de los parámetros de ruta utilizando el método

where
. Este método acepta el nombre del parámetro y una expresión regular que define el patrón permitido.

Route::get('/usuarios/{id}', function ($id) {
return 'Usuario ' . $id;
})->where('id', '[0-9]+'); // Solo números
// Múltiples restricciones
Route::get('/posts/{post}/comentarios/{comentario}', function ($postId, $comentarioId) {
// Lógica de la ruta
})->where([
'post' => '[0-9]+',
'comentario' => '[0-9]+'
]);
// Restricciones comunes
Route::get('/categoria/{slug}', function ($slug) {
// Lógica de la ruta
})->whereAlpha('slug'); // Solo caracteres alfabéticos

Si deseas que un parámetro de ruta siga siempre un patrón específico en toda tu aplicación, puedes definir restricciones globales en el método

boot
de
RouteServiceProvider
:

// En app/Providers/RouteServiceProvider.php
public function boot(): void
{
Route::pattern('id', '[0-9]+'); // Todas las {id} deben ser numéricas
// ...
}

Las rutas nombradas te permiten generar URLs o redirecciones a rutas específicas sin tener que recordar sus URIs. Esto es útil cuando las URIs cambian, ya que solo necesitarás actualizar la definición de la ruta, no todas las referencias a ella en tu código.

Para asignar un nombre a una ruta, utiliza el método

name
en la definición de la ruta:

Route::get('/perfil/usuario', function () {
// Lógica de la ruta
})->name('perfil.usuario');
// Con controlador
Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');

Una vez que has asignado un nombre a una ruta, puedes generar URLs o redirecciones utilizando los helpers

route()
o
redirect()->route()
:

// Generar una URL
$url = route('perfil.usuario'); // http://ejemplo.com/perfil/usuario
// Con parámetros
$url = route('usuarios.show', ['id' => 1]); // http://ejemplo.com/usuarios/1
// Con parámetros y query string
$url = route('usuarios.index', ['sort' => 'nombre', 'order' => 'asc']);
// http://ejemplo.com/usuarios?sort=nombre&order=asc
// Redireccionar a una ruta nombrada
return redirect()->route('perfil.usuario');
// Redireccionar con parámetros
return redirect()->route('usuarios.show', ['id' => 1]);

Puedes verificar si la ruta actual coincide con un nombre específico utilizando el método

named()
de la fachada
Route
:

// Verificar si la ruta actual es 'perfil.usuario'
if (Route::currentRouteName() === 'perfil.usuario') {
// Lógica específica
}
// O usando el helper named()
if (Route::named('perfil.*')) {
// Coincide con cualquier ruta que comience con 'perfil.'
}

En las plantillas Blade, puedes generar URLs a rutas nombradas utilizando el helper

route()
:

<a href="{{ route('perfil.usuario') }}">Ver perfil</a>
<!-- Con parámetros -->
<a href="{{ route('usuarios.show', ['id' => $usuario->id]) }}">Ver usuario</a>
<!-- Verificar la ruta actual para marcar elementos de menú como activos -->
<a href="{{ route('dashboard') }}" class="{{ Route::currentRouteName() === 'dashboard' ? 'active' : '' }}">
Dashboard
</a>

La agrupación de rutas te permite compartir atributos comunes, como middleware, prefijos de URL, espacios de nombres de controladores y más, entre un conjunto de rutas sin tener que definir estos atributos en cada ruta individual.

Para crear un grupo de rutas, utiliza el método

Route::group()
:

Route::group([], function () {
Route::get('/usuarios', function () {
// ...
});
Route::get('/usuarios/{id}', function ($id) {
// ...
});
});

El atributo

prefix
te permite añadir un prefijo a todas las rutas dentro del grupo:

Route::group(['prefix' => 'admin'], function () {
// Ruta: /admin/dashboard
Route::get('/dashboard', function () {
return 'Panel de administración';
});
// Ruta: /admin/usuarios
Route::get('/usuarios', [AdminController::class, 'usuarios']);
// Rutas anidadas: /admin/reportes/ventas
Route::prefix('reportes')->group(function () {
Route::get('/ventas', [ReporteController::class, 'ventas']);
Route::get('/usuarios', [ReporteController::class, 'usuarios']);
});
});

El atributo

middleware
te permite aplicar uno o varios middleware a todas las rutas del grupo:

// Aplicar un solo middleware
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/perfil', [PerfilController::class, 'show']);
});
// Aplicar múltiples middleware
Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/configuracion', [ConfiguracionController::class, 'index']);
Route::post('/configuracion', [ConfiguracionController::class, 'update']);
});

El atributo

namespace
te permite especificar un espacio de nombres para los controladores dentro del grupo:

Route::namespace('AppHttpControllersAdmin')->group(function () {
// Los controladores estarán en AppHttpControllersAdmin
Route::get('/dashboard', [DashboardController::class, 'index']);
});

El atributo

name
te permite añadir un prefijo a todos los nombres de rutas dentro del grupo:

admin.dashboard
Route::name('admin.')->group(function () {
Route::get('/admin/dashboard', function () {
// ...
})->name('dashboard');
// Nombre de ruta: admin.usuarios.index
Route::get('/admin/usuarios', function () {
// ...
})->name('usuarios.index');
});

Puedes agrupar rutas por dominio o subdominio utilizando el atributo

domain
:

// Rutas para un subdominio específico
Route::domain('admin.ejemplo.com')->group(function () {
Route::get('/', [AdminController::class, 'index']);
});
// Rutas con parámetros de subdominio
Route::domain('{cuenta}.ejemplo.com')->group(function () {
Route::get('/', function ($cuenta) {
return 'Cuenta: ' . $cuenta;
});
});

Puedes combinar múltiples atributos en un solo grupo:

Route::prefix('api')
->middleware(['api', 'auth:api'])
->namespace('AppHttpControllersApi')
->name('api.')
->group(function () {
Route::get('/usuarios', [UsuarioController::class, 'index'])->name('usuarios.index');
Route::post('/usuarios', [UsuarioController::class, 'store'])->name('usuarios.store');
});

Laravel proporciona varias formas de devolver respuestas desde tus rutas, incluyendo redirecciones, respuestas JSON, descargas de archivos y más.

La forma más simple de devolver una respuesta es retornando una cadena de texto o un array desde una ruta o controlador:

Route::get('/saludo', function () {
return 'Hola mundo'; // Respuesta de texto simple
});
Route::get('/datos', function () {
return ['nombre' => 'Juan', 'edad' => 30]; // Se convierte automáticamente a JSON
});

Puedes especificar un código de estado HTTP personalizado utilizando el helper

response()
:

Route::get('/no-autorizado', function () {
return response('No autorizado', 401);
});
Route::get('/no-encontrado', function () {
return response('No encontrado', 404);
});

Puedes añadir encabezados HTTP personalizados a tus respuestas:

Route::get('/documento', function () {
return response('Contenido del documento')
->header('Content-Type', 'text/plain')
->header('X-Header-Personalizado', 'Valor personalizado');
});

Para devolver una respuesta JSON con el encabezado

Content-Type: application/json
, utiliza el método
json()
:

Route::get('/api/usuarios', function () {
return response()->json([
'nombre' => 'Juan',
'apellido' => 'Pérez',
'email' => 'juan@ejemplo.com'
]);
});
// Con código de estado personalizado
Route::post('/api/usuarios', function () {
return response()->json(['mensaje' => 'Usuario creado'], 201);
});

Para redireccionar a otra URL o ruta, utiliza el helper

redirect()
:

// Redireccionar a una URL
Route::get('/redirigir', function () {
return redirect('https://laravel.com');
});
// Redireccionar a una ruta nombrada
Route::get('/ir-a-inicio', function () {
return redirect()->route('inicio');
});
// Redireccionar a una ruta con parámetros
Route::get('/ir-a-perfil', function () {
return redirect()->route('usuarios.perfil', ['id' => 1]);
});
// Redireccionar a la página anterior
Route::post('/cancelar', function () {
return redirect()->back();
});
// Redireccionar con datos de sesión flash
Route::post('/guardar', function () {
return redirect()->route('dashboard')
->with('mensaje', 'Datos guardados correctamente');
});

Para generar una respuesta de descarga de archivo, utiliza el método

download()
:

// Descargar un archivo con su nombre original
Route::get('/descargar/archivo', function () {
return response()->download(storage_path('app/archivo.pdf'));
});
// Descargar con un nombre personalizado
Route::get('/descargar/reporte', function () {
return response()->download(
storage_path('app/reportes/datos.pdf'),
'reporte-anual.pdf'
);
});
// Mostrar un archivo en el navegador en lugar de descargarlo
Route::get('/ver/imagen', function () {
return response()->file(storage_path('app/public/imagen.jpg'));
});

Para devolver una vista como respuesta, utiliza el helper

view()
:

Route::get('/bienvenida', function () {
return view('bienvenida');
});
// Con datos para la vista
Route::get('/perfil/{id}', function ($id) {
$usuario = Usuario::find($id);
return view('usuarios.perfil', ['usuario' => $usuario]);
});
// Con datos usando el método with()
Route::get('/dashboard', function () {
return view('dashboard')
->with('nombre', 'Juan')
->with('rol', 'Administrador');
});

El sistema de rutas de Laravel es flexible y potente, permitiendo organizar fácilmente cómo tu aplicación responde a las solicitudes HTTP. Utilizando las características como rutas nombradas, agrupación y parámetros, puedes crear una estructura de rutas limpia y mantenible para tu aplicación.

🐝