Menu
CoddyTech

Die Reihenfolge ist wichtig

Teil des Abschnitts Express-Grundlagen der Node.js-Journey von Coddy. Lektion 12 von 20.

Express führt Middleware und Routen in der Reihenfolge aus, in der dein Code sie hinzufügt, und eine Route, die eine Antwort sendet, beendet die Anfrage an dieser Stelle.

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

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

res.set(name, value) fügt der Antwort einen Header hinzu und muss ausgeführt werden, bevor die Antwort gesendet wird. Hier antwortet GET /bikes, bevor die Middleware erreicht wird, sodass die Antwort nie den Header erhält: Die Middleware sieht nur Anfragen, auf die keine darüberliegende Route geantwortet hat. Middleware, die jede Antwort beeinflussen soll, kommt vor die Routen und vor express.static.

challenge icon

Aufgabe

Einfach

Jede Antwort, einschließlich Seiten und Dateien, enthält einen X-Request-Id-Header mit einer neuen randomUUID() aus node:crypto.

Sende zweimal GET /api/recipes und vergleiche die Header. Sende anschließend GET /style.css.

Probier es selbst

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') sendet reinen Text, sodass jeder Titel in einer eigenen Zeile erscheint.
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');
});

Alle Lektionen in Express-Grundlagen