Capítulo 5.5: Enrutamiento para páginas web
Tiempo de estudio: 40 minutos
1. routes/web.php
vs routes/api.php
: Dos paneles de control diferentes
Es importante consolidar una vez más la diferencia fundamental:
Característica | routes/web.php (Panel web) |
routes/api.php (Panel API) |
---|---|---|
Tarea principal | Visualización de páginas HTML, procesamiento de formularios | Provisión de datos en formato JSON para otras aplicaciones |
Estado | Stateful (con estado) — utiliza sesiones y cookies | Stateless (sin estado) — cada solicitud es independiente |
Middleware predeterminado | web (incluye sesiones, protección CSRF, cifrado de cookies) |
api (incluye "throttling" — limitación de la frecuencia de solicitudes) |
Prefijo de URL | No (raíz de su sitio) | /api/ (configurable en RouteServiceProvider ) |
Autenticación | Normalmente a través de sesiones (Login/Contraseña) | Normalmente a través de tokens (Sanctum, Passport) |
Trabajamos con routes/web.php
para construir una interfaz para un ser humano.
2. Rutas de recursos para la web
Similar a Route::apiResource
, para la web existe Route::resource
. Crea rutas para el ciclo CRUD completo, incluyendo páginas para mostrar formularios de creación y edición.
Creemos un conjunto completo de rutas para gestionar nuestras planetas a través de la interfaz web.
Paso 1: Creamos la ruta en routes/web.php
Comente o elimine las rutas antiguas para /planets
y reemplácelas con una sola línea:
use App\Http\Controllers\Web\PlanetPageController;
// Route::get('/planets', [PlanetPageController::class, 'index']);
// Route::get('/planets/{planet}', [PlanetPageController::class, 'show']);
Route::resource('planets', PlanetPageController::class);
Paso 2: Veamos qué se creó
Ejecute en la terminal el comando php artisan route:list --except-vendor
:
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| GET|HEAD | planets | planets.index | ...\PlanetPageController@index | web |
| POST | planets | planets.store | ...\PlanetPageController@store | web |
| GET|HEAD | planets/create | planets.create | ...\PlanetPageController@create | web |
| GET|HEAD | planets/{planet} | planets.show | ...\PlanetPageController@show | web |
| PUT|PATCH | planets/{planet} | planets.update | ...\PlanetPageController@update | web |
| DELETE | planets/{planet} | planets.destroy | ...\PlanetPageController@destroy | web |
| GET|HEAD | planets/{planet}/edit | planets.edit | ...\PlanetPageController@edit | web |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
Route::resource
creó para nosotros 7 rutas, incluyendo:
planets.create
(GET/planets/create
): página con el formulario de creación.planets.store
(POST/planets
): procesamiento de este formulario.planets.edit
(GET/planets/{planet}/edit
): página con el formulario de edición.planets.update
(PUT/PATCH/planets/{planet}
): procesamiento del formulario de edición.planets.destroy
(DELETE/planets/{planet}
): eliminación del recurso.
3. Rutas con nombre: Convenientes "coordenadas cósmicas"
Preste atención a la columna Name
. Laravel asignó automáticamente un nombre único a cada ruta (por ejemplo, planets.index
). Usar nombres en lugar de URL codificadas es una mejor práctica.
¿Por qué? Si decide cambiar la URL de /planets
a /worlds
, no tendrá que buscar y cambiar todos los enlaces en sus plantillas. Simplemente lo cambia en un solo lugar — en el archivo de rutas, y los nombres permanecen iguales.
Ejemplo de uso en Blade:
Antes escribíamos así:
Ahora escribiremos así, usando el helper route()
:
route('planets.show', ...)
— genera la URL para la ruta con el nombreplanets.show
.['planet' => $planet->id]
— pasa los parámetros necesarios a la URL. Laravel mismo sustituirá el ID en{planet}
. Incluso se puede pasar el modelo completo:['planet' => $planet]
.
4. Implementación de los métodos faltantes en el controlador
Route::resource
creó las rutas, pero necesitamos crear nosotros mismos los métodos correspondientes en PlanetPageController
.
Abra app/Http/Controllers/Web/PlanetPageController.php
y agreguémoslos.
<?php
use Illuminate\Http\Request; // <-- Añadir
class PlanetPageController extends Controller
{
// Ya tenemos index() y show()
/**
* Muestra el formulario para crear un nuevo planeta.
*/
public function create()
{
return view('planets.create'); // Simplemente retornamos la vista con el formulario
}
/**
* Guarda un nuevo planeta en la base de datos.
*/
public function store(Request $request)
{
// Validación de los datos del formulario
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets',
'solar_system' => 'required|string|max:100',
// ... otras reglas
]);
Planet::create($validated);
// Redirigimos al usuario a la página de la lista con un mensaje de éxito
return redirect()->route('planets.index')->with('success', '¡Planeta creado exitosamente!');
}
/**
* Muestra el formulario para editar un planeta.
*/
public function edit(Planet $planet)
{
return view('planets.edit', ['planet' => $planet]);
}
/**
* Actualiza los datos de un planeta en la base de datos.
*/
public function update(Request $request, Planet $planet)
{
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets,name,' . $planet->id,
'solar_system' => 'required|string|max:100',
]);
$planet->update($validated);
return redirect()->route('planets.show', $planet)->with('success', '¡Datos del planeta actualizados!');
}
/**
* Elimina un planeta.
*/
public function destroy(Planet $planet)
{
$planet->delete();
return redirect()->route('planets.index')->with('success', 'Planeta dado de baja.');
}
}
redirect()->route(...)
— redirige al usuario a otra ruta con nombre.->with('success', '...')
— añade un "mensaje flash" a la sesión, que estará disponible en la siguiente página exactamente una vez. Podemos mostrarlo en nuestra plantilla Blade.
5. Agrupación de rutas
Si tiene muchas rutas con características comunes (por ejemplo, todas son para el panel de administración y deben tener el prefijo /admin
y un middleware especial), pueden agruparse.
<?php
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
// Todas las rutas dentro de este grupo tendrán:
// 1. Middleware 'auth' y 'admin'
// 2. Prefijo de URL '/admin' (por ejemplo, /admin/planets)
// 3. Prefijo de nombre 'admin.' (por ejemplo, admin.planets.index)
Route::resource('planets', PlanetPageController::class);
// Route::get('/dashboard', ...)->name('dashboard'); // -> admin.dashboard
});
Cuestionario para afianzar conocimientos
🚀 Resumen del capítulo:
Has dominado un enfoque estructurado y profesional para la organización de rutas web en Laravel. Ahora sabes cómo:
- Distinguir las rutas
web
yapi
y su propósito. - Usar
Route::resource
para generar rápidamente rutas CRUD estándar. - Aplicar rutas nombradas para crear código flexible y mantenible.
- Crear operaciones CRUD completas en el controlador con validación y redirecciones.
- Agrupar rutas para aplicar reglas comunes.
El sistema de navegación de su "nave" ahora es tolerante a fallos y está listo para expandirse. En el capítulo final de esta sección, combinaremos todo el conocimiento adquirido y mostraremos los datos de los planetas, obtenidos a través de Fetch, en nuestra página Blade.