Menu
CoddyTech

L’ordre compte

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

Express exécute les middlewares et les routes dans l’ordre où votre code les ajoute, et une route qui répond met fin à la requête à cet endroit.

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

app.use((req, res, next) => {
    res.set('Cache-Control', 'no-store');
    next();
});

res.set(name, value) ajoute un en-tête à la réponse, et cette méthode doit être exécutée avant l’envoi de la réponse. Ici, GET /bikes répond avant que le middleware ne soit atteint, donc sa réponse ne reçoit jamais l’en-tête : le middleware ne voit que les requêtes auxquelles aucune route située au-dessus n’a répondu. Les middlewares qui doivent intervenir sur chaque réponse se placent au-dessus des routes et de express.static.

challenge icon

Défi

Facile

Chaque réponse, y compris les pages et les fichiers, comporte un en-tête X-Request-Id contenant un nouvel randomUUID() provenant de node:crypto.

Envoyez deux fois GET /api/recipes et comparez les en-têtes, puis envoyez GET /style.css.

Essayez vous-même

import express from 'express';
import { recipes } from './data.js';

const app = express();

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

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

const escapeHtml = (text) =>
    text
        .replaceAll('&', '&')
        .replaceAll('<', '&lt;')
        .replaceAll('>', '&gt;')
        .replaceAll('"', '&quot;');

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');
});

Toutes les leçons de Les bases d’Express