Menu
CoddyTech

Il tuo primo middleware

Fa parte della sezione Fondamenti di Express del percorso Node.js di Coddy. Lezione 13 di 23.

Alcune operazioni riguardano ogni richiesta, come scrivere una riga nel log, e copiarle in ogni route non finirebbe mai. Ogni richiesta ha un metodo, in req.method: GET per recuperare qualcosa, POST per inviare qualcosa.

let visits = 0;

app.use((req, res, next) => {
    visits++;
    next();
});

Una funzione passata a app.use è un middleware: Express la esegue per ogni richiesta, nell'ordine in cui è stata aggiunta, prima delle route che la seguono. Riceve un terzo argomento, next. Chiamando next(), la richiesta passa a ciò che viene dopo. Un middleware che non risponde né chiama next() lascia la richiesta in attesa per sempre.

Anche express.static del capitolo precedente è un middleware: risponde quando trova un file e chiama next() quando non lo trova.

challenge icon

Sfida

Facile

Vuoi una riga di log per ogni richiesta ricevuta dal tuo server, così puoi vedere cosa chiedono i visitatori.

  1. In server.js, subito dopo const app = express();, aggiungi un middleware con app.use. Messo lì, viene eseguito prima di ogni route.
  2. Per ogni richiesta, stampa una riga nella Console: il metodo della richiesta, uno spazio e poi il suo percorso. Una richiesta a /recipes/2 stampa GET /recipes/2. Il metodo si trova in req.method (GET, POST e così via) e il percorso in req.url.
  3. Dopo aver stampato, chiama next(), così la richiesta prosegue verso le route.

Prova: premi «Gioca» e invia /recipes/2. Dovresti vedere Pancakes e la Console mostra GET /recipes/2. Invia /api/recipes: la lista come al solito e GET /api/recipes nella Console. Invia /nope: un 404 e la Console mostra comunque GET /nope, perché il middleware viene eseguito prima che Express cerchi una route.

Provalo tu

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

const app = express();

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') invia testo semplice, quindi ogni titolo appare su una riga a sé.
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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Fondamenti di Express

Esercitati da solo: Playground Express