Valider les entrées
Fait partie de la section API REST du Journey Node.js de Coddy. Leçon 6 sur 25.
Un client peut envoyer n’importe quoi dans un corps de requête, et if (!name) ne bloque que les valeurs vides. 123, true et ["x"] sont des valeurs truthy et passent. Une chaîne composée d’espaces passe aussi : détectez-la avec trim(), puisque ' '.trim() donne ''. Vérifiez le type de chaque champ avec typeof, puis ses limites :
const { seats } = req.body ?? {};
if (typeof seats !== 'number' || !Number.isInteger(seats) || seats < 1) {
return res.status(400).json({ error: 'seats must be a whole number from 1' });
}Rédigez le message à l’intention de la personne qui lit la réponse : nommez le champ et indiquez ce qu’il doit être, afin qu’elle sache quoi corriger. Une requête PATCH vérifie uniquement les champs qui lui ont été envoyés, puisque les autres ne changent pas.
Défi
FacileActuellement, if (!title) laisse passer un titre comme 123 ou " ". Vérifie le type et la taille de chaque champ avant de l’enregistrer.
- Dans
routes/tasks.js, dans la route POST, vérifietitle:- Il doit s’agir d’une chaîne de caractères.
- Elle ne doit pas être vide ni contenir uniquement des espaces.
- Elle doit comporter au maximum 100 caractères, espaces compris.
Si l’une de ces conditions n’est pas remplie, renvoie le statut 400 et un message d’erreur qui contient le mot
title, par exemple :{ "error": "title must be a string of 1 to 100 characters" } - Dans la route PATCH, vérifie uniquement les champs envoyés dans le corps de la requête :
- S’il envoie
title, la même règle s’applique, ainsi que le même type de message d’erreur. - S’il envoie
done, sa valeur doit êtretrueoufalse. Sinon, renvoie le statut 400 et une erreur qui contient le motdone:
Un PATCH refusé ne modifie rien.{ "error": "done must be true or false" } - S’il envoie
- Les corps de requête valides continuent de fonctionner : POST renvoie toujours 201, et un PATCH avec
{ "done": true }renvoie toujours 200. Laisse PUT tel quel ; Schemas le vérifie aussi avec zod.
Essaie : envoie POST { "title": 123 } à /api/tasks : tu obtiens 400 avec l’erreur concernant title. Envoie POST { "title": " " } : tu obtiens aussi 400. Envoie PATCH /api/tasks/2 avec { "done": "yes" } : tu obtiens 400 avec l’erreur concernant done, et GET /api/tasks/2 affiche toujours "done": false. Envoie PATCH /api/tasks/2 avec { "done": true } : tu obtiens 200.
Essayez vous-même
import { Router } from 'express';
import { nextId, tasks } from '../store.js';
const router = Router();
router.get('/', (req, res) => {
res.json(tasks);
});
router.get('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return res.status(404).json({ error: 'Task not found' });
}
res.json(task);
});
router.post('/', (req, res) => {
const { title } = req.body ?? {};
if (!title) {
return res.status(400).json({ error: 'title is required' });
}
const task = { id: nextId(), title, done: false, createdAt: new Date().toISOString() };
tasks.push(task);
res.status(201).location(`/api/tasks/${task.id}`).json(task);
});
router.patch('/:id', (req, res) => {
const task = tasks.find((t) => t.id === Number(req.params.id));
if (!task) {
return res.status(404).json({ error: 'Task not found' });
}
const { title, done } = req.body ?? {};
if (title !== undefined) task.title = title;
if (done !== undefined) task.done = done;
res.json(task);
});
router.put('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'Task not found' });
}
const { title, done } = req.body ?? {};
if (title === undefined || done === undefined) {
return res.status(400).json({ error: 'PUT needs every field: title and done' });
}
const { id, createdAt } = tasks[index];
tasks[index] = { id, title, done, createdAt };
res.json(tasks[index]);
});
router.delete('/:id', (req, res) => {
const index = tasks.findIndex((t) => t.id === Number(req.params.id));
if (index === -1) {
return res.status(404).json({ error: 'Task not found' });
}
tasks.splice(index, 1);
res.status(204).end();
});
export default router;
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de API REST
1Ressources et verbes
Ressources et URLCréer avec POST4Navigateurs, versions et configuration
Qu’est-ce qu’une origineAutoriser une autre origineCORSUne page qui appelle l’API2Validation et erreurs
Valider les entréesEntraînez-vous par vous-même : Playground Express