Express.js: routing, middleware ed error handling
app.use(), router modulare, express.json() e i middleware di errore a quattro parametri
Express è, nelle parole della documentazione ufficiale, un framework web minimale e flessibile per Node.js. Sopra il modulo http nativo aggiunge un sistema di routing e un meccanismo di middleware che tolgono di mezzo gran parte del codice ripetitivo necessario per gestire richieste, risposte ed errori a mano.
Un'applicazione Express funziona come un ufficio con più sportelli in fila. Ogni richiesta in arrivo passa da uno sportello all'altro (i middleware), e ciascuno può leggerla, modificarla o timbrarla, prima di farla proseguire allo sportello successivo. Solo alla fine della fila la richiesta arriva a chi deve davvero rispondere (la route).
1. Un server minimo con Express
Un'applicazione Express nasce da poche righe: si crea l'app, si definisce cosa rispondere a un percorso, si mette il server in ascolto su una porta.
const express = require('express');
const app = express();
app.get('/', (richiesta, risposta) => {
risposta.send('Ciao dal server Express!');
});
app.listen(3000, () => {
console.log('Server in ascolto sulla porta 3000');
});
Fonte: la guida ufficiale «Hello world example» mostra il server Express minimo di partenza.
2. Il routing: rispondere a metodi e percorsi diversi
Express mette a disposizione un metodo per ciascun metodo HTTP (app.get(), app.post(), app.put(), app.delete()), e permette di definire parti variabili del percorso con i due punti, leggibili poi da richiesta.params.
app.get('/prodotti/:id', (richiesta, risposta) => {
const id = richiesta.params.id;
risposta.send(`Dettaglio del prodotto numero ${id}`);
});
app.post('/prodotti', (richiesta, risposta) => {
risposta.status(201).send('Prodotto creato');
});
3. I middleware: funzioni che intercettano la richiesta
Un middleware è semplicemente una funzione con tre parametri: la richiesta, la risposta, e una terza funzione chiamata per convenzione next. Chiamare next() passa il controllo al middleware successivo nella fila; se nessuno la chiama, la richiesta resta bloccata lì per sempre, senza mai ricevere risposta.
function logRichiesta(richiesta, risposta, next) {
console.log(`${richiesta.method} ${richiesta.url}`);
next();
}
app.use(logRichiesta);
Un middleware senza next() è come una guardia al controllo passaporti che trattiene un passeggero senza mai farlo passare, e senza nemmeno rimandarlo indietro: il passeggero resta lì, in coda, per sempre.
4. express.json(): leggere il corpo delle richieste
Per leggere un corpo JSON inviato dal client (per esempio da un fetch() con metodo POST) serve il middleware integrato express.json(), che analizza il corpo della richiesta e lo rende disponibile in richiesta.body. Senza registrarlo, richiesta.body resta indefinito, qualunque cosa sia stata inviata.
app.use(express.json());
app.post('/prodotti', (richiesta, risposta) => {
const nuovoProdotto = richiesta.body;
risposta.status(201).json(nuovoProdotto);
});
Fonte: il riferimento API ufficiale documenta express.json() e le sue opzioni di configurazione.
5. Router modulare: organizzare le rotte in file separati
Quando le rotte crescono, conviene raggrupparle per argomento invece di tenerle tutte in un unico file. express.Router() crea un mini modulo di routing indipendente, agganciabile poi all'applicazione principale con un prefisso comune.
// routes/prodotti.js
const express = require('express');
const router = express.Router();
router.get('/', (richiesta, risposta) => {
risposta.send('Elenco prodotti');
});
module.exports = router;
// app.js
const prodottiRouter = require('./routes/prodotti');
app.use('/prodotti', prodottiRouter);
6. Gestire gli errori: il middleware a quattro parametri
Express riconosce un middleware come dedicato alla gestione degli errori guardando semplicemente quanti parametri dichiara la sua funzione: quattro invece di tre, con l'errore come primo parametro. Va sempre registrato per ultimo, dopo tutte le altre rotte e gli altri middleware.
app.use((errore, richiesta, risposta, next) => {
console.error(errore.stack);
risposta.status(500).send('Qualcosa non ha funzionato sul server.');
});

In sintesi
Express aggiunge a Node.js routing per verbo e percorso, e un sistema di middleware in cui ogni funzione può leggere, modificare o interrompere una richiesta prima che raggiunga la rotta finale, purché ricordi di chiamare next() per farla proseguire. express.json() abilita la lettura del corpo delle richieste, express.Router() permette di organizzare le rotte in moduli separati, e un ultimo middleware a quattro parametri chiude la catena gestendo qualunque errore non intercettato prima. Nella prossima pillola, dedicata al mondo NodeJS, vedremo come aggiungere TypeScript a un backend Node.js.
Commenti (0)
Registrati per commentare, fare domande e proporre l'argomento della prossima pillola (oppure accedi se hai già un account).
Nessun commento. Sii il primo a scrivere qualcosa.