Il tuo primo Web Server: Hello World dal Browser
Chiudiamo la guida pratica creando un server HTTP nativo con ES Modules. Scopri la potenza del web asincrono.
Siamo arrivati alla tappa finale di questo viaggio. Abbiamo esplorato l’architettura, dominato l’asincronia e configurato NPM. Ma Node.js brilla davvero quando diventa il motore del Web.
Invece di affidarti a server preconfigurati (come Apache o Nginx), con Node.js scriviamo noi il codice del server. Questa flessibilità è ciò che ha reso Node.js lo standard per le applicazioni moderne ad alte prestazioni.
Grazie all’architettura Non-Blocking I/O che abbiamo studiato nei capitoli precedenti, questo semplice server può gestire migliaia di connessioni simultanee con un consumo di risorse minimo.
Il Modulo Nativo: http
Node.js mette a disposizione il modulo node:http. Sebbene nel mondo reale useremo framework come Express o Fastify, capire come funziona il modulo nativo è essenziale per comprendere il flusso Richiesta/Risposta.
Ogni volta che un utente visita il tuo indirizzo, avvengono due cose:
- Request (req): Il server riceve un oggetto contenente i dati del visitatore (URL, browser usato, dati inviati).
- Response (res): Il server deve rispondere inviando uno stato (es. 200 OK) e il contenuto (HTML, JSON, immagini).
Preparare il Progetto
Creiamo l’ultima sottocartella nella nostra directory progetti-nodejs:
mkdir primo-server
cd primo-server
npm init -y
Ricorda di aggiungere "type": "module" al package.json. Poi crea il file del server:
# Linux/macOS
touch server.js
# Windows (PowerShell)
New-Item server.js -ItemType File
Creazione del Server Web
Apri server.js e utilizza la potenza degli ES Modules per inizializzare il tuo primo server.
import { createServer } from "node:http"
// Creiamo un'istanza del server
const server = createServer((req, res) => {
// 1. Definiamo il tipo di contenuto (HTML con supporto emoji)
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" })
// 2. Scriviamo il corpo della pagina
res.write("<h1>Benvenuto sul mio server Node.js! 🚀</h1>")
res.write(
`<p>Stai visualizzando il percorso: <strong>${req.url}</strong></p>`
)
// 3. Importante: segnaliamo che la risposta è terminata
res.end()
})
// Definiamo la porta di ascolto (3000 è lo standard per lo sviluppo)
const PORT = 3000
server.listen(PORT, () => {
console.log("-----------------------------------------")
console.log(`✅ Server attivo!`)
console.log(`🌐 Indirizzo: http://localhost:${PORT}`)
console.log("-----------------------------------------")
})
Come testare il tuo server
- Avvia il processo: Nel terminale, scrivi
node server.js. - Apri il Browser: Vai all’indirizzo
http://localhost:3000. - Sperimenta: Prova a navigare su
http://localhost:3000/chi-siamoohttp://localhost:3000/blog. Noterai che l’app riconosce il percorso che scrivi nell’URL!
Routing e Risposte Diverse
Il server che abbiamo scritto risponde allo stesso modo per qualsiasi indirizzo. Nel mondo reale ogni percorso — o route — ha una risposta diversa. Node.js ci mette a disposizione req.url per sapere quale indirizzo è stato richiesto e req.method per sapere il tipo di operazione (GET, POST, DELETE, ecc.).
import { createServer } from "node:http"
const server = createServer((req, res) => {
// Route: GET / → pagina HTML
if (req.method === "GET" && req.url === "/") {
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" })
res.end("<h1>Benvenuto!</h1>")
return
}
// Route: GET /api/saluto → risposta JSON
if (req.method === "GET" && req.url === "/api/saluto") {
const dati = { messaggio: "Ciao dal server!", versione: "1.0" }
res.writeHead(200, { "Content-Type": "application/json" })
res.end(JSON.stringify(dati))
return
}
// Nessuna route trovata → 404
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" })
res.end("Pagina non trovata")
})
server.listen(3000, () => {
console.log("Server attivo su http://localhost:3000")
})
Visita http://localhost:3000/api/saluto nel browser: riceverai un oggetto JSON, non HTML. È esattamente così che si costruiscono le API.
Il numero nel primo argomento di writeHead non è decorativo.
Browser, client API e motori di ricerca lo usano per interpretare il
risultato: 200 è successo, 404 è “non trovato”,
500 è errore del server. Usarli correttamente è la base di
qualsiasi API professionale.
Automatizzano esattamente questo lavoro: sostituiscono il blocco if/else manuale con un sistema di routing dichiarativo. Ora che sai cosa c’è sotto, capirai il loro codice sin dal primo giorno.
Analisi delle Operazioni
È una funzione di “ascolto”. Non blocca il computer; resta lì, in attesa che l’Event Loop riceva una connessione.
Comunichiamo al browser che tutto è andato bene (codice 200) e che tipo di file stiamo inviando. Senza questo, il browser potrebbe non capire come visualizzare il testo.
È il segnale di chiusura del pacchetto. Se lo dimentichi, il browser continuerà a caricare all’infinito perché “pensa” che il server debba ancora dire qualcosa.
🎉 Congratulazioni!
Hai completato con successo il modulo “Primi Passi con Node.js”. Ora hai le basi solide per affrontare sfide più grandi:
- Creare API REST professionali.
- Usare database come MongoDB o PostgreSQL.
- Sviluppare applicazioni in tempo reale con WebSockets.
Qual è il prossimo passo? Continua a sperimentare: modifica il server per restituire JSON, aggiungi più route, o prova a gestire gli errori con un codice 404.