Skip to content

Chapitre 5.5 : Routage pour les pages web

Temps d'étude : 40 minutes


1. routes/web.php vs routes/api.php : Deux panneaux de contrôle différents

Il est important de bien comprendre la différence fondamentale :

Caractéristique routes/web.php (Panneau web) routes/api.php (Panneau API)
Tâche principale Affichage de pages HTML, traitement de formulaires Fourniture de données au format JSON pour d'autres applications
État (State) Stateful (avec état) — utilise les sessions et les cookies Stateless (sans état) — chaque requête est indépendante
Middleware par défaut web (inclut les sessions, la protection CSRF, le chiffrement des cookies) api (inclut le "throttling" — limitation de la fréquence des requêtes)
Préfixe d'URL Aucun (racine de votre site) /api/ (configurable dans RouteServiceProvider)
Authentification Habituellement via sessions (Login/Mot de passe) Habituellement via tokens (Sanctum, Passport)

Nous travaillons avec routes/web.php pour construire une interface pour un être humain.


2. Routes de ressources pour le web

Semblable à Route::apiResource, il existe Route::resource pour le web. Il crée des routes pour un cycle CRUD complet, y compris des pages pour afficher les formulaires de création et d'édition.

Créons un ensemble complet de routes pour gérer nos planètes via l'interface web.

Étape 1 : Créer la route dans routes/web.php

Commentez ou supprimez les anciennes routes pour /planets et remplacez-les par une seule ligne :

use App\Http\Controllers\Web\PlanetPageController;

// Route::get('/planets', [PlanetPageController::class, 'index']);
// Route::get('/planets/{planet}', [PlanetPageController::class, 'show']);

Route::resource('planets', PlanetPageController::class);

Étape 2 : Vérifier ce qui a été créé Exécutez la commande php artisan route:list --except-vendor dans le terminal :

+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| 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 a créé 7 routes pour nous, incluant :

  • planets.create (GET /planets/create) : page avec le formulaire de création.
  • planets.store (POST /planets) : traitement de ce formulaire.
  • planets.edit (GET /planets/{planet}/edit) : page avec le formulaire d'édition.
  • planets.update (PUT/PATCH /planets/{planet}) : traitement du formulaire d'édition.
  • planets.destroy (DELETE /planets/{planet}) : suppression de la ressource.

3. Routes nommées : Des "coordonnées spatiales" pratiques

Notez la colonne Name. Laravel a automatiquement attribué un nom unique à chaque route (par exemple, planets.index). Utiliser des noms au lieu d'URL codées en dur est une meilleure pratique.

Pourquoi ? Si vous décidez de changer l'URL de /planets à /worlds, vous n'aurez pas à chercher et modifier tous les liens dans vos templates. Vous le changez simplement à un seul endroit — dans le fichier de routes, et les noms restent les mêmes.

Exemple d'utilisation dans Blade :

Avant, nous écrivions ceci :

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

Maintenant, nous écrirons ceci, en utilisant l'aideur route() :

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

  • route('planets.show', ...) — génère une URL pour la route nommée planets.show.
  • ['planet' => $planet->id] — transmet les paramètres nécessaires à l'URL. Laravel substituera l'ID dans {planet}. On peut même passer le modèle entier : ['planet' => $planet].

4. Implémentation des méthodes manquantes dans le contrôleur

Route::resource a créé les routes, mais nous devons créer nous-mêmes les méthodes correspondantes dans PlanetPageController.

Ouvrez app/Http/Controllers/Web/PlanetPageController.php et ajoutons-les.

<?php
use Illuminate\Http\Request; // <-- À ajouter

class PlanetPageController extends Controller
{
    // index() et show() sont déjà présents

    /**
     * Affiche le formulaire pour créer une nouvelle planète.
     */
    public function create()
    {
        return view('planets.create'); // Nous retournons simplement la vue avec le formulaire
    }

    /**
     * Enregistre une nouvelle planète dans la base de données.
     */
    public function store(Request $request)
    {
        // Validation des données du formulaire
        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:planets',
            'solar_system' => 'required|string|max:100',
            // ... autres règles
        ]);

        Planet::create($validated);

        // Redirige l'utilisateur vers la page de liste avec un message de succès
        return redirect()->route('planets.index')->with('success', 'Planète créée avec succès !');
    }

    /**
     * Affiche le formulaire pour modifier une planète.
     */
    public function edit(Planet $planet)
    {
        return view('planets.edit', ['planet' => $planet]);
    }

    /**
     * Met à jour les données de la planète dans la base de données.
     */
    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', 'Données de la planète mises à jour !');
    }

    /**
     * Supprime une planète.
     */
    public function destroy(Planet $planet)
    {
        $planet->delete();

        return redirect()->route('planets.index')->with('success', 'Planète supprimée.');
    }
}
  • redirect()->route(...) — redirige l'utilisateur vers une autre route nommée.
  • ->with('success', '...') — ajoute un "message flash" à la session, qui sera disponible sur la page suivante une seule fois. Nous pouvons l'afficher dans notre template Blade.

5. Groupement de routes

Si vous avez de nombreuses routes avec des caractéristiques communes (par exemple, toutes sont destinées au panneau d'administration et doivent avoir le préfixe /admin et un middleware spécial), elles peuvent être regroupées.

<?php
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
    // Toutes les routes à l'intérieur de ce groupe auront :
    // 1. Les middlewares 'auth' et 'admin'
    // 2. Le préfixe d'URL '/admin' (par exemple, /admin/planets)
    // 3. Le préfixe de nom 'admin.' (par exemple, admin.planets.index)

    Route::resource('planets', PlanetPageController::class);
    // Route::get('/dashboard', ...)->name('dashboard'); // -> admin.dashboard
});

Quiz de consolidation

1. Quelle commande dans `routes/web.php` créera un ensemble complet de routes CRUD pour l'interface web ?

2. Quel est le principal avantage de l'utilisation des routes nommées ?

3. Quelle route sera générée pour la méthode `create()` dans `Route::resource('articles', ...)` ?

4. Que fait le code `redirect()->route('home')->with('status', 'OK')` ?

5. À quoi sert `Route::prefix('dashboard')` ?

    for (const [question, correctAnswer] of Object.entries(correctAnswers)) {
      const questionDiv = form.querySelector(`input[name="${question}"]`).closest('.question');
      const labels = questionDiv.querySelectorAll('label');
      labels.forEach(l => {
          l.style.color = 'inherit';
          l.style.fontWeight = 'normal';
          l.style.border = 'none';
      });

      const userAnswer = form.elements[question] ? form.elements[question].value : undefined;

      if (userAnswer) {
        const selectedLabel = form.querySelector(`input[name="${question}"][value="${userAnswer}"]`).parentElement;
        if (userAnswer === correctAnswer) {
          score++;
          selectedLabel.style.fontWeight = 'bold';
          resultsHTML += `<li>Question ${question.slice(1)}: <span style="color:green;">Correct !</span></li>`;
        } else {
          selectedLabel.style.fontWeight = 'bold';
          const correctLabel = form.querySelector(`input[name="${question}"][value="${correctAnswer}"]`).parentElement;
          correctLabel.style.fontWeight = 'bold';
          resultsHTML += `<li>Question ${question.slice(1)}: <span style="color:red;">Incorrect.</span> Bonne réponse : <b>${correctAnswer.toUpperCase()}</b></li>`;
        }
      } else {
        resultsHTML += `<li>Question ${question.slice(1)}: <span style="color:orange;">Pas de réponse.</span></li>`;
      }
    }

    resultsHTML += `</ul><p><b>Votre résultat : ${score} sur ${Object.keys(correctAnswers).length}</b></p>`;
    resultsContainer.innerHTML = resultsHTML;
    resultsContainer.style.display = 'block';
  }
</script>

---

**🚀 Résumé du chapitre :**

Vous avez maîtrisé une approche structurée et professionnelle pour l'organisation des routes web dans Laravel. Vous savez maintenant :

-   Distinguer les routes `web` et `api` et leur objectif.
-   Utiliser `Route::resource` pour générer rapidement des routes CRUD standard.
-   Appliquer des routes nommées pour créer un code flexible et maintenable.
-   Créer des opérations CRUD complètes dans le contrôleur avec validation et redirections.
-   Grouper les routes pour appliquer des règles communes.

**Le système de navigation de votre "navire" est désormais résilient et prêt à être étendu.** Dans le dernier chapitre de cette section, nous combinerons toutes les connaissances acquises et afficherons les données des planètes, obtenues via Fetch, sur notre page Blade.