Skip to content

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í:

<a href="/planets/{{ $planet->id }}">Узнать больше &rarr;</a>

Ahora escribiremos así, usando el helper route():

<a href="{{ route('planets.show', ['planet' => $planet->id]) }}">Узнать больше &rarr;</a>

  • route('planets.show', ...) — genera la URL para la ruta con el nombre planets.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

1. ¿Qué comando en `routes/web.php` creará un conjunto completo de rutas CRUD para la interfaz web?

2. ¿Cuál es la principal ventaja de usar rutas nombradas?

3. ¿Qué ruta se generará para el método `create()` en `Route::resource('articles', ...)`?

4. ¿Qué hace el código `redirect()->route('home')->with('status', 'OK')`?

5. ¿Para qué se usa `Route::prefix('dashboard')`?

🚀 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 y api 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.