
Gestion des routes : définir les points d'accès de votre API
Apprenez a definir et gerer les routes dans Express.js en utilisant les methodes HTTP (GET, POST...) et les chemins d'URL pour structurer votre application web ou API.
Qu'est-ce que le routage dans une application web ?
Au coeur de toute application web ou API se trouve le mécanisme de routage. Le routage détermine comment l'application répond à une requête client en fonction de l'URL (le chemin ou "path") demandée et de la méthode HTTP utilisée (GET, POST, PUT, DELETE, etc.). Essentiellement, c'est le système qui aiguille une requête entrante vers le bon morceau de code (le "handler" ou gestionnaire) chargé de la traiter.
Dans l'approche de base avec le module `http` de Node.js, nous devions implémenter ce routage manuellement, souvent avec une série de structures `if/else if` basées sur `req.url` et `req.method`. Bien que fonctionnelle pour des cas simples, cette approche devient rapidement désordonnée, difficile à lire et à maintenir à mesure que le nombre de points d'accès (endpoints) de l'application augmente.
Express.js brille particulièrement dans ce domaine en offrant un système de routage élégant, puissant et très lisible. Il permet de définir clairement quelles fonctions doivent être exécutées pour quelles combinaisons de méthode HTTP et de chemin d'URL, rendant la structure de l'application beaucoup plus organisée.
La syntaxe de base du routage Express : `app.METHOD(PATH, HANDLER)`
La définition d'une route dans Express suit une structure simple et intuitive. Elle est généralement attachée à l'objet représentant votre application Express (souvent nommé `app`) :
app.METHOD(PATH, HANDLER);Décortiquons chaque partie :
- `app` : L'instance de votre application Express, créée par `const app = express();`.
- `METHOD` : Correspond à la méthode HTTP de la requête que vous souhaitez intercepter, écrite en minuscules. Express fournit des méthodes dédiées pour toutes les méthodes HTTP courantes : `app.get()`, `app.post()`, `app.put()`, `app.delete()`, `app.patch()`, etc. Il existe aussi `app.all()` pour intercepter toutes les méthodes HTTP pour un chemin donné.
- `PATH` : Une chaîne de caractères représentant le chemin de l'URL auquel cette route doit répondre. Cela peut être une chaîne simple comme `'/'` (la racine), `'/users'`, `'/about'`, ou des chemins plus complexes contenant des motifs ou des paramètres (que nous verrons plus tard).
- `HANDLER` : C'est la fonction qui sera exécutée si une requête entrante correspond à la `METHOD` et au `PATH` spécifiés. Cette fonction est souvent appelée "gestionnaire de route" ou "route handler". Elle reçoit toujours au moins deux arguments : l'objet requête (`req`) et l'objet réponse (`res`), similaires à ceux du module `http` mais enrichis par Express avec des méthodes et propriétés supplémentaires très utiles. Une troisième fonction, `next`, est également souvent passée pour la gestion des middlewares, que nous aborderons bientôt.
Gerer differentes methodes et chemins
Avec cette syntaxe, vous pouvez facilement définir des réponses différentes pour la même URL en fonction de la méthode HTTP, ou gérer plusieurs URL différentes.
Exemple de définition de plusieurs routes :
const express = require('express');
const app = express();
const port = 3000;
// Route pour la page d'accueil (GET sur /)
app.get('/', (req, res) => {
res.send('Bienvenue sur la page d\'accueil !');
});
// Route pour la page 'A propos' (GET sur /about)
app.get('/about', (req, res) => {
res.send('Ceci est la page A propos.');
});
// Route pour lister des utilisateurs (GET sur /api/users)
app.get('/api/users', (req, res) => {
// En pratique, on irait chercher des données dans une BDD
const users = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
res.json(users); // Express simplifie l'envoi de JSON
});
// Route pour créer un nouvel utilisateur (POST sur /api/users)
app.post('/api/users', (req, res) => {
// Ici, il faudrait lire le corps de la requête (req.body)
// Express nécessite un middleware (ex: express.json()) pour parser le corps
console.log('Tentative de création d\'un utilisateur...');
// Simuler une création réussie
res.status(201).json({ id: 3, message: 'Utilisateur créé' }); // Envoyer un statut 201 et du JSON
});
// Route pour toutes les autres méthodes sur /about (exemple)
app.all('/about', (req, res) => {
res.status(405).send('Méthode non autorisée pour /about'); // 405 Method Not Allowed
});
// Gestionnaire pour les routes non trouvées (doit être défini APRES toutes les autres routes)
app.use((req, res) => {
res.status(404).send('Désolé, cette page n\'existe pas !');
});
app.listen(port, () => {
console.log(`Application Express démarrée sur http://localhost:${port}`);
});
Dans cet exemple :
- Une requête `GET /` est gérée par la première fonction.
- Une requête `GET /about` est gérée par la deuxième.
- Une requête `GET /api/users` liste les utilisateurs (en renvoyant du JSON grâce à `res.json()`).
- Une requête `POST /api/users` simule la création d'un utilisateur (renvoyant un statut `201 Created` avec `res.status(201)`).
- Toute autre méthode sur `/about` renvoie une erreur 405.
- Toute autre requête non interceptée par les routes précédentes aboutit au gestionnaire 404 final (via `app.use`).
L'ordre de définition des routes est important. Express les teste dans l'ordre où elles sont définies. La première qui correspond à la requête entrante sera exécutée.
Le role du gestionnaire de route (`handler`)
La fonction `handler` est le coeur de votre logique métier pour une route donnée. Elle reçoit les objets `req` et `res`.
- `req` (Requête) : Contient les informations sur la requête entrante : `req.method`, `req.url`, `req.headers`, mais aussi des ajouts d'Express comme `req.params` (pour les paramètres de route), `req.query` (pour les paramètres de requête), et `req.body` (pour le corps de la requête, après utilisation d'un middleware de parsing).
- `res` (Réponse) : Offre des méthodes simplifiées pour envoyer la réponse :
- `res.send([body])` : Méthode polyvalente qui peut envoyer des chaînes, des Buffers, des objets (qui seront convertis en JSON), ou des tableaux. Définit automatiquement l'en-tête `Content-Type`.
- `res.json([body])` : Envoie explicitement une réponse JSON. Convertit l'objet ou le tableau fourni en JSON et définit `Content-Type` à `application/json`.
- `res.status(code)` : Définit le code de statut HTTP et retourne l'objet `res` pour permettre le chaînage (ex: `res.status(404).send(...)`).
- `res.sendStatus(code)` : Définit le code de statut et envoie la représentation textuelle du code comme corps (ex: `res.sendStatus(404)` envoie "Not Found").
- `res.render(...)` : Utilisée avec les moteurs de template pour rendre une vue HTML.
- `res.redirect([status,] path)` : Effectue une redirection HTTP.
- Et bien d'autres (`res.sendFile`, `res.download`, etc.).
Le handler est responsable de traiter la requête et d'utiliser l'objet `res` pour renvoyer une réponse appropriée au client. Si le handler ne termine pas le cycle requête-réponse (en appelant `res.send`, `res.json`, `res.end`, etc.), le client restera en attente.
Conclusion : structurer votre application avec les routes
Le système de routage d'Express.js est l'une de ses caractéristiques les plus fondamentales et appréciées. Il transforme la tâche potentiellement complexe de diriger les requêtes HTTP en un processus déclaratif, lisible et facile à gérer.
En définissant clairement des gestionnaires pour chaque combinaison de méthode HTTP et de chemin d'URL, vous créez une structure logique pour votre application web ou votre API. Cela facilite non seulement le développement initial mais aussi la maintenance et l'évolution future de votre code. Nous explorerons ensuite comment rendre ces routes encore plus dynamiques avec les paramètres et comment utiliser les middlewares pour ajouter des fonctionnalités transversales.