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 :
Maintenant, nous écrirons ceci, en utilisant l'aideur route()
:
route('planets.show', ...)
— génère une URL pour la route nomméeplanets.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
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.