Die Reihenfolge ist wichtig
Teil des Abschnitts Express-Grundlagen der Node.js-Journey von Coddy. Lektion 14 von 23.
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, daher erhält die Antwort nie den Header: Die Middleware sieht nur Anfragen, die von keiner darüberliegenden Route beantwortet wurden. Middleware, die jede Antwort beeinflussen soll, kommt vor die Routen und vor express.static.
Aufgabe
EinfachJede Antwort erhält eine ID, damit du die Anfrage in deinem Protokoll finden kannst, wenn ein Besucher ein Problem meldet. Jede Antwort braucht eine: Seiten, API-Daten und Dateien aus public.
- Importiere in
server.jsrandomUUIDausnode:crypto. Jeder Aufruf gibt eine neue zufällige ID zurück, zum Beispiel3b241101-e2bb-4255-8caf-4136c566a962. - Füge eine Middleware hinzu, die einen Antwort-Header namens
X-Request-Idmit einer neuenrandomUUID()für jede Anfrage setzt und anschließendnext()aufruft. - Platziere sie so, dass jede Anfrage sie durchläuft, auch die für Dateien, die
express.staticsendet. Eine Antwort erhält den Header nur, wenn die Middleware ausgeführt wird, bevor etwas antwortet.
Probiere es aus: Drücke auf „Run“ und sende zweimal /api/recipes. Im Tab „Headers“ hat X-Request-Id jedes Mal einen anderen Wert. Sende /style.css und /: Beide enthalten ebenfalls ein X-Request-Id.
Probier es selbst
import { escapeHtml } from './html.js';
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'));
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
Übe selbstständig: Express-Playground