Lire le corps d'une requête POST
Flux, collecte du corps et validation des entrées.
Objectifs
À la fin de cette leçon, vous saurez :
- comprendre pourquoi le corps arrive en flux et non d'un bloc ;
- collecter les morceaux et reconstruire le JSON ;
- valider les entrées avant de les accepter.
🔗 Pour vous rafraîchir la mémoire : streams et pipe() · en-têtes HTTP et JSON · curl pas à pas
Le corps arrive en morceaux
Le corps d'une requête peut être énorme : Node ne le charge pas d'un bloc, il le transmet en flux (streams, un mécanisme appris au chapitre 18). On écoute deux événements sur la requête :
"data" → un morceau de plus (Buffer)
"end" → tout est arrivé
Collecter et parser
function lireCorps(requete) {
return new Promise(function (resoudre, rejeter) {
const morceaux = [];
requete.on("data", function (morceau) {
morceaux.push(morceau);
});
requete.on("end", function () {
resoudre(Buffer.concat(morceaux).toString("utf8"));
});
requete.on("error", rejeter);
});
}
Emballé dans une Promise, ce motif devient consommable avec await — la fusion de vos chapitres asynchronisme + HTTP :
if (requete.method === "POST" && chemin === "/tasks") {
const brut = await lireCorps(requete);
try {
const { titre } = JSON.parse(brut);
if (!titre || typeof titre !== "string") {
return repondreJSON(reponse, 400, { erreur: "Titre requis" });
}
const tache = { id: Date.now(), titre };
taches.push(tache);
return repondreJSON(reponse, 201, tache);
} catch {
return repondreJSON(reponse, 400, { erreur: "JSON invalide" });
}
}
Valider TOUT ce qui entre
Ce corps vient de l'extérieur : il est hostile par nature. Trois contrôles systématiques :
- Parse : est-ce du JSON valide ? → try/catch → 400.
- Présence/type : titre existe-t-il ? Est-ce une chaîne ? → 400.
- Bornes (à ajouter) : longueur max raisonnable, champs inattendus ignorés.
C'est votre première validation d'entrées serveur — le principe que NestJS automatisera avec ses DTO. La règle ne changera jamais : ne jamais faire confiance à une donnée entrante.
Test complet :
curl -X POST localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"titre": "Ma première tâche API"}'
curl -X POST localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"pasDeTitre": true}' # → 400
Exercice
- Intégrez
lireCorpset la route POST ci-dessus à votre serveur. - Ajoutez la limite : titre de 200 caractères max → 400 au-delà.
- Testez les quatre cas : succès, JSON cassé, champ manquant, champ trop long.
- Pourquoi valider aussi côté client ET côté serveur ?
Résumé
- Corps = flux : data/end, Buffer.concat pour recomposer.
- Promise autour = consommable avec await.
- Validation systématique : parse → présence/type → bornes ; jamais de confiance.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
Question 2.
if (typeof titre !== "string" || titre.length === 0 || titre.length > 200) {
return repondreJSON(reponse, 400, { erreur: "Titre requis (200 car. max)" });
}
Question 4. Le client valide pour l'expérience utilisateur (retour immédiat) ; le serveur revalide parce que n'importe qui peut contourner le client avec curl. La validation client est un confort ; la validation serveur est une sécurité — c'est elle seule qui compte réellement.