Implementazione di un server web completo

La lezione conclusiva del ciclo di lezioni introduttive a Node.js mostra come implementare un server HTTP applicando quanto discusso nelle varie lezioni.

Il server completo

A questo punto abbiamo completato il codice del modulo “module-02.js” (la classe HttpDispatcher) e abbiamo a disposizione una risorsa HTML da servire all’utente quando viene richiesta la root del server. Per completare l’applicazione resta solo da aggiungere il codice che registra i listeners (che verranno gestiti dal dispatcher), e poi eseguire il server principale. Per comodità riportiamo qui sotto il codice completo del server:

come accennato, la parte “più noiosa” è la registrazione dei listeners. Qui sopra abbiamo scelto di registrare i listeners uno alla volta. In un’applicazione professionale potremmo leggere la lista dei listeners da una risorsa (ad esempio un file INI) e poi registrare i vari listeners usando un ciclo for. Una modifica di questo tipo può essere un ottimo esercizio.

Notiamo che le richieste alla root del server sono esaudite da un listeners che accede al file system, restituendo la risorsa home.html di pagina precedente. Questa non è l’unica scelta possibile, ma spesso risulta comoda. Il codice che accede al file system potrebbe essere modificato per gestire un intero albero di directories, eseguendo le opportune operazioni di analisi sul pattern dell’URL richiesto al server.

Per eseguire l’applicazione collochiamo tutte le risorse (server.js, module-02.js e home.html) nella stessa directory, dopodiché eseguiamo il server come al solito (cioè node server.js). Aprendo il browser all’indirizzo specificato, che nel nostro caso sarà http://localhost:8080, dovremo trovare la pagina HTML che abbiamo configurato come home. Da qui possiamo navigare i vari link per testare gli URL gestiti dal dispatcher, sia di tipo HTTP GET che di tipo HTTP POST.

Il prodotto finale utilizza un pattern che possiamo utilizzare anche per applicazioni professionali. Chiaramente è necessario migliorare gli aspetti che abbiamo già evidenziato, che ripetiamo: registrare i listeners in modo automatico (leggendoli da un file di configurazione); migliorare il metodo che accede al file system (per poter servire tutte le risorse che vogliamo rendere accessibili); aggiungere il codice di gestione degli errori (risorsa mancante o listeners non trovato). Tutte queste modifiche andrebbero apportate rispettando il pattern modulare, ottenendo due vantaggi: un’applicazione più facile da mantenere e la possibilità di centralizzare (e riutilizzare) il codice.