Prise en main d'Express : trois exercices d'API
Ces trois exercices servent à prendre en main Express.js. pour la construction d’APIs. Chaque exercice ajoute une notion : d’abord les opérations de base, ensuite la validation des données reçues, enfin la mise à jour d’une ressource avec la question « qui a le droit de la modifier ».
Objectifs
Section intitulée « Objectifs »Au terme de ces exercices, tu devrais pouvoir :
- Définir des routes Express pour les principaux verbes HTTP et répondre en JSON.
- Valider les données d’une requête et renvoyer des erreurs claires.
- Mettre à jour une ressource en tenant compte de son propriétaire.
Prérequis
Section intitulée « Prérequis »- Node.js installé (version 18 ou plus récente).
- npm (fourni avec Node.js).
- Un client HTTP pour envoyer des requêtes : Bruno ou Postman.
Mise en place
Section intitulée « Mise en place »Crée un dossier de projet, puis installe Express :
mkdir table-apicd table-apinpm init -ynpm install expressCrée un fichier server.js avec un serveur minimal :
import express from 'express';
const app = express();app.use(express.json()); // interprète le corps JSON des requêtes
app.get('/', (req, res) => { res.json({ message: 'Le serveur répond.' });});
const PORT = 3000;app.listen(PORT, () => { console.log(`Serveur démarré sur http://localhost:${PORT}`);});Lance le serveur avec node server.js, puis envoie une requête GET http://localhost:3000/ depuis Bruno ou Postman. Tu devrais recevoir le message JSON.
Arborescence suggérée pour toute la page (un seul fichier suffit au début) :
table-api/ package.json server.jsMini-glossaire
Section intitulée « Mini-glossaire »Ces termes reviennent dans les trois exercices.
- Route (ou endpoint, point d’accès) : l’association d’un verbe HTTP et d’un chemin, par exemple
GET /students. C’est l’adresse à laquelle le client s’adresse. - Verbe HTTP : l’action demandée. On utilise surtout
GET(lire),POST(créer),PUT(remplacer),DELETE(supprimer). - Code de statut : un nombre à trois chiffres qui résume le résultat. Par exemple 200 (succès), 201 (créé), 400 (requête invalide), 404 (introuvable), 403 (interdit).
- En mémoire (in-memory) : les données sont stockées dans une variable JavaScript. Elles disparaissent quand le serveur redémarre. C’est suffisant pour s’entraîner, sans base de données.
Exercice 1 — CRUD d’une liste d’étudiants
Section intitulée « Exercice 1 — CRUD d’une liste d’étudiants »Objectif. Construire les quatre opérations de base sur une ressource.
Crée une API permettant de gérer une liste d’étudiants stockée en mémoire. Chaque étudiant possède un id (généré par le serveur), un nom et un courriel. Expose les cinq routes suivantes :
GET /students: renvoie la liste complète.GET /students/:id: renvoie un étudiant, ou 404 s’il n’existe pas.POST /students: ajoute un étudiant et renvoie l’objet créé avec le code 201.PUT /students/:id: remplacenometcourriel, ou 404 s’il n’existe pas.DELETE /students/:id: supprime l’étudiant, ou 404 s’il n’existe pas.
Étapes suggérées.
-
Déclare la structure de données et un compteur d’identifiants :
let students = [];let nextId = 1; -
Écris les routes une à une, en testant chacune dans ton client avant de passer à la suivante.
-
Pour retrouver un étudiant,
students.find(s => s.id === Number(req.params.id)). Le paramètre d’URL arrive sous forme de texte, d’où la conversion en nombre.
Vérification
POST /studentsavec{ "nom": "Ada", "courriel": "ada@exemple.ca" }répond 201 et renvoie l’objet avec unid.GET /studentsrépond 200 et contient l’étudiant créé.GET /students/1répond 200 ;GET /students/999répond 404.PUT /students/1avec de nouvelles valeurs répond 200 et les modifications sont visibles au prochainGET.DELETE /students/1répond 200 (ou 204) ; un secondDELETE /students/1répond 404.
Exercice 2 — Système d’inscription
Section intitulée « Exercice 2 — Système d’inscription »Objectif. Refuser proprement les données invalides.
La Brasserie Pete organise des ateliers et veut recueillir les inscriptions.
Une inscription comporte un nom, un courriel et une cohorte.
Expose une route POST /inscriptions qui n’enregistre l’inscription que si les données sont valides :
nom: présent et non vide.courriel: présent et contenant un@.cohorte: présente et faisant partie de la liste autorisée, par exemple["matin", "soir"].
En cas d’erreur, réponds avec le code 400 et un corps qui décrit tous les problèmes rencontrés, pas seulement le premier :
{ "errors": [ { "champ": "courriel", "message": "Le courriel doit contenir un @." }, { "champ": "cohorte", "message": "La cohorte doit être matin ou soir." } ]}Si tout est valide, enregistre l’inscription en mémoire et réponds 201 avec l’objet créé.
Vérification
POST /inscriptionsavec un objet complet et valide répond 201.- Un
courrielsans@fait répondre 400 avec une erreur sur le champcourriel. - Une
cohorteabsente ou hors liste fait répondre 400 avec une erreur sur le champcohorte. - Une requête à la fois sans
nomet sanscourrielrépond 400 avec deux erreurs.
Exercice 3 — Commentaires modifiables
Section intitulée « Exercice 3 — Commentaires modifiables »Objectif. Mettre à jour une ressource en vérifiant qui en est l’auteur.
Crée une API qui gère une liste de commentaires en mémoire. Chaque commentaire a un id, un author (le nom de l’auteur) et un text. Expose :
GET /comments: renvoie tous les commentaires.POST /comments: crée un commentaire à partir de{ author, text }, répond 201.PUT /comments/:id: remplace letextdu commentaire, mais seulement si celui qui demande la modification est l’auteur.
Pour identifier le demandeur de façon simple, attends un champ author dans le corps de la requête PUT. Compare-le à l’auteur enregistré :
- Commentaire introuvable : 404.
authordu corps différent de l’auteur enregistré : 403 (interdit).- Sinon : remplace le texte et réponds 200.
Vérification
POST /commentsavec{ "author": "Ada", "text": "Bonne idée." }répond 201.PUT /comments/1avec{ "author": "Ada", "text": "Excellente idée." }répond 200 et le texte est modifié au prochainGET.PUT /comments/1avec{ "author": "Bob", "text": "..." }répond 403 et le texte reste inchangé.PUT /comments/999répond 404.
À retenir
Section intitulée « À retenir »- Une route associe un verbe HTTP et un chemin ; la réponse porte toujours un code de statut, qui a autant de sens que le corps.
- Le CRUD couvre les quatre opérations de base et se traduit par les verbes
GET,POST,PUT,DELETE. - La validation se fait avant l’enregistrement et signale les refus par un code 4xx, idéalement en listant toutes les erreurs d’un coup.
- Distinguer 404 (la ressource n’existe pas) de 403 (elle existe, mais l’action n’est pas permise) aide le client à réagir correctement.
- Garder la logique (validation, recherche) dans des fonctions séparées des routes rend le code plus lisible et plus facile à faire évoluer, par exemple lorsqu’on passera à plusieurs services.