Nell'azienda per cui lavoro, Sysdig, faccio parte del team di ingegneri che dedicano la loro vita lavorativa a Sysdig Monitor (per chi fosse interessato più dettagli nel sito). Tralasciando che cosa il prodotto sia o faccia, per lo scopo di questo post basti pensare che esso è stato sviluppato sotto forma di SPA: Single Page Application, mi piacerebbe dunque spiegare brevemente che cosa sono e a cosa servono.
Applicazioni a pagina singola
Questo tipo di applicazioni non sono una novità e sebbene esistano da qualche anno, non sono ancora diffuse nello sviluppo di servizi fruibili ad un utente medio. Tuttavia, negli ultimi anni le SPA sono state adottate molto più per costruire piattaforme private SaaS (Software as a Service) o applicazioni data-driven ad alta intensità di traffico. La tendenza sembrerebbe cambiare, portando le single page app ad essere utilizzate maggiormente anche in ambito Business to Customer (B2C).
Di cosa si tratta
Spesso, i nomi dati alle tecnologie non sono molto azzeccati, non hanno nulla a che vedere con l’innovazione che introducono e ciò può portare a molta confusione. Pensiamo ad esempio al Bluetooth, il famoso sistema per lo scambio di dati attraverso onde radio a corto raggio. Esso fu chiamato in quel modo in quanto uno degli ingegneri a capo del progetto aveva da poco letto Le navi dei vichinghi di Frans G. Bengtsson, un libro che tra le altre cose parla dei viaggi di guerrieri danesi durante il regno di Aroldo I detto blátǫnn, che significa dente blu (o dente Azzurro, in inglese blue tooth) appunto. Inizialmente il nome dato dall’ingegnere fu provvisorio, infine venne confermato.
Questo non è certamente il caso delle SPA: esse sono realmente un'applicazione che utilizzano una sola pagina! Navigando su di una SPA, si può notare che la pagina non viene mai ricaricata, i nuovi dati vengono costantemente aggiornati mentre l'utente utilizza l'applicazione. Se si utilizza un tool che analizza le richieste di rete come quello presente nella console per sviluppatori di Google Chrome, si può notare che il primo file scaricato sarà index.html. Questo rappresenta letteralmente la singola pagina della nostra app. Attenzione: non stiamo affermando che una SPA sia formata da un singolo file: durante lo sviluppo, il progetto potrà essere composto da molti file diversi, ma con il processo di deployment, necessario per caricare in produzione il progetto, tutto il contenuto sarà inserito in quell’unica risorsa. Voi stessi in questo momento state leggendo questo contenuto da una SPA 😅.
Il problema che tentano di risolvere
Perché vogliamo scrivere applicazioni a pagina singola?
La ragione principale è che per ora, nonostante l’ambiente di interazione tra l’utente ed il servizio da noi creato sia sempre il browser, esse ci consentono di offrire un'esperienza molto più vicina a quella delle app native rispetto a qualsiasi altra metodologia. Supportare numerose interazioni con più componenti in una pagina significa che tali componenti possono assumere numerosi stati intermedi prima di giungere a quello che l’utente sta effettivamente vedendo o utilizzando. Il rendering lato server è difficile da implementare a causa di tutti questi possibili stati, ed essi, qualora siano anche piccoli cambiamenti di visualizzazione, non possono essere mappati sugli URL con facilità (si tratterebbe di avere un URL diverso per ogni stato eventualmente assumibile dal componente e per di più per ogni componente!).
Le applicazioni a pagina singola si distinguono per la loro capacità di ridisegnare qualsiasi parte dell'interfaccia utente senza necessità di effettuare alcuna richiesta al server per farsi restituire l'HTML necessario. Questo è possibile separando i dati veri e propri dalla parte che ha la funzione di rappresentazione dei dati, utilizzando un livello per il modello (model layer) che gestisce i dati ed un livello di visualizzazione (view layer) che legge i dati dai modelli.
La maggior parte dei progetti inizia con livelli di ambizione elevatissimi ma con una conoscenza del problema da risolvere non completa. L’implementazione della soluzione a quel problema tende a superare la nostra comprensione e porta a scrivere codice più complesso di quello che avrebbe potuto essere a causa della nostra ignoranza al riguardo. Il buon codice deriva dall’esperienza, che può essere definita come il risolvere diverse istanze di uno stesso problema più volte.
Acquisendo esperienza si riescono a notare pattern ripetuti e si può sostituire codice specifico, che tende a risolvere la singola istanza del problema, con codice generico, diventando così un meccanismo che risolve non la singola istanza, bensì tutta la classe di problemi di quello stesso genere in modo coerente. Le architetture utilizzate nelle SPA rappresentano il risultato di questo processo: dove in passato si facevano cose ad hoc con gli strumenti che illustreremo nei prossimi post, ora si scrive codice che sfrutta meccanismi standard.
Perle di saggezza
Come dice Rich Hickey in uno dei suoi talk:
I programmatori sono ossessionati dalla facilità piuttosto che dalla semplicità.
Effettivamente questi due vocaboli possono sembrare sinonimi ma non lo sono: la semplicità è la condizione di chi o di ciò che è semplice, naturale, sobrio. Facilità significa caratteristica di ciò che è facile, predisposizione o attitudine naturale a fare qualche cosa senza sforzo. Vengono spesso usati come sinonimi, ma non sempre è possibile farlo perchè hanno accezioni diverse. Un esempio banale di tale fatto è presto dato: si può dire che un vestito sia semplice ma non che sia facile!
Ciò porta i developer a conversazioni futili sul dove posizionare i punti e virgola e se abbiamo bisogno di un preprocessore che elimina le parentesi graffe. Si parla di programmazione come se digitare il codice fosse la parte ardua, mentre una delle parti più difficili è la manutenzione della codebase. Può assumere dimensioni notevoli, parti di essa possono essere state sviluppate anni prima e ad un certo punto si ha la necessità di cambiarle, e la persona addetta a far ciò potrebbe non essere l’autore originale, oppure anche lo fosse sfido chiunque a ricordarsi ogni linea di codice scritta dopo un bel po’ di tempo.
Per scrivere codice manutenibile si devono fare le cose semplici. È un principio con il quale vi è una lotta costante. È molto facile aggiungere complessità e interdipendenza usando bad practices per risolvere un problema all’apparenza banale, ed è facile risolvere un problema in modo che non riduca la complessità.
In conclusione
Le SPA, rimanendo su un piano concettuale ed andando aldilà del framework o pattern utilizzato, offrono uno strumento solido con una struttura ben definita per far vivere all'utente la stessa esperienza (o per lo meno quanto più possibile simile) vissuta utilizzando un app nativa. Tutto ciò si ottiene avendo un singolo caricamento iniziale per l'impostazione dell'ambiente e continui scambi di informazione tra client e server che rimangono trasparenti agli occhi dell'utilizzatore.
Nei prossimi giorni scriverò un post per capire come si sia arrivati dal passato ad avere questo tipo di applicazioni e perchè si portano dietro le scelte implementative che oggi notiamo.