Menu
CoddyTech

Lire un corps de requête

Fait partie de la section Les bases d’Express du Journey Node.js de Coddy. Leçon 15 sur 23.

Une requête POST envoie des données dans son corps, et Express ne lit pas ce corps à moins que tu le lui demandes.

app.use(express.json());

app.post('/api/loans', (req, res) => {
    const { bookId, member } = req.body;
    res.status(201).json({ bookId, member, due: '2026-11-08' });
});

GET demande quelque chose ; POST envoie quelque chose à créer. express.json() est un middleware qui lit chaque corps JSON dans req.body. Sans lui, req.body vaut undefined. Une route qui crée quelque chose répond avec le statut 201 et ce qu’elle a créé.

Vérifie le corps avant de l’enregistrer. Un champ manquant est une erreur du client : réponds donc avec le statut 400 et n’enregistre rien.

challenge icon

Défi

Facile

Les visiteurs peuvent ajouter leurs propres recettes. Un programme envoie la nouvelle recette au format JSON dans le corps d’une requête POST, et votre API l’enregistre.

  1. Dans server.js, ajoutez express.json() aux autres lignes app.use, au-dessus des routes, afin qu’un corps JSON soit disponible dans req.body.
  2. Ajoutez une route pour les requêtes POST vers /api/recipes. Elle lit title et tags dans le corps, par exemple {"title": "Miso Soup", "tags": ["vegan", "soup"]}.
  3. Elle crée la nouvelle recette avec le prochain identifiant numérique : les quatre recettes ont les identifiants 1 à 4, donc la première nouvelle recette reçoit l’identifiant 5. Elle conserve le titre et les étiquettes qui lui ont été envoyés. Si aucun tags n’a été envoyé, utilisez une liste vide, [].
  4. Elle ajoute la recette au tableau recipes, afin que GET /api/recipes la répertorie. Elle répond ensuite avec le statut 201 et la nouvelle recette au format JSON : {"id": 5, "title": "Miso Soup", "tags": ["vegan", "soup"]}
  5. Si le corps ne contient pas de title, elle n’enregistre rien et répond avec le statut 400 et ce JSON : {"error": "A recipe needs a title"}

Essayez : Appuyez sur « Jouer ». Choisissez POST dans le sélecteur de méthode, saisissez /api/recipes comme chemin et mettez {"title": "Miso Soup", "tags": ["vegan", "soup"]} dans le champ du corps. Vous devriez voir le statut 201 et la recette avec "id": 5. Choisissez GET et envoyez /api/recipes : cinq recettes, avec Miso Soup en dernier. Envoyez ensuite POST {"tags": ["dinner"]} à /api/recipes : statut 400 et {"error":"A recipe needs a title"}. GET /api/recipes répertorie toujours cinq recettes.

Essayez vous-même

import { escapeHtml } from './html.js';
import express from 'express';
import { randomUUID } from 'node:crypto';
import { recipes } from './data.js';

const app = express();

app.use((req, res, next) => {
    console.log(`${req.method} ${req.url}`);
    next();
});

app.use((req, res, next) => {
    res.set('X-Request-Id', randomUUID());
    next();
});

app.use(express.static('public'));

app.get('/', (req, res) => {
    const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
    res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});

// type('text') envoie du texte brut, donc chaque titre apparaît sur sa propre ligne.
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/api/recipes', (req, res) => {
    res.json(recipes);
});

app.get('/api/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    res.json(recipe);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.get('/menu', (req, res) => {
    res.redirect(301, '/recipes');
});

app.get('/menu/:id', (req, res) => {
    res.redirect(301, `/recipes/${req.params.id}`);
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Les bases d’Express

Entraînez-vous par vous-même : Playground Express