Sentiamo sempre più spesso parlare di Cloud Computing, di collaborazione fra sistemi distribuiti ed eterogenei. In tale ottica, Web Service e tecnologie come SOAP, XML, HTTP assumono importanza e rilievo ai fini di una scalabilità e una rappresentazioni dei dati e delle funzioni quanto più semplice possibile: REST è una architettura che nasce proprio per semplificare tali aspetti. Nella serie che comincia con questo articolo, alcuni dei nostri autori affronteranno al meglio queste tecnologie, con una prospettiva non usuale e ci auguriamo molto interessante per i lettori.
Introduzione
Uno degli argomenti caldi dell’ultimo anno è stato il Cloud Computing: sistemi distribuiti ed eterogenei possono collaborare nella realizzazione di una qualche funzionalità di business. In questo contesto assume sempre maggiore importanza il concetto di servizio che, in molti ma non in tutti i casi, si traduce tecnologicamente in quella cosa che chiamiamo Web Services. E naturalmente, associamio i Web Service a tecnologie ben precise: SOAP, XML, HTTP e via dicendo.
In ogni caso, in tale ottica, restano fondamentali alcuni punti fissi per chiunque intenda fornire un servizio:
- il proprio servizio può essere acceduto da moltissime applicazioni, anche sconosciute, che ne vogliono utilizzare le funzionalità;
- la funzionalità realizzata non dovrà mai dipendere da quella del servizio che ne usufruirà.
In una architettura di questo tipo alcuni requisiti diventano cruciali: per esempio la scalabilità, il modo in cui vengono rappresentate le funzioni e i dati dati. Tutto questo deve essere reso più semplice possibile ed questa la ragione per cui nasce REST.
Che cosa è REST?
Representational State Transfer (REST) è uno stile di architettura software per sistemi ipermediali distribuiti. Un sistema conforme ai design principle REST è detto RESTful. Il Web è l’esempio più importante e più famoso di sistema distribuito che realizza i principi REST. D’altra parte non è un caso. Infatti Roy Fielding, il padre di REST, introdusse per la prima volta l’espressione Representational State Transfer nella sua tesi di dottorato [2] per indicare le caratteristiche delle parti meglio progettate del Web [3].
Il termine REST è diventato più comune negli ultimi anni con l’esplosione del Web 2.0 e il proliferare di servizi web. Con la popolarità, il termine REST ha assunto anche significati diversi e scorretti fino a diventare in molti casi una buzzword. Per questa ragione in questo articolo vorrei fare un po’ di chiarezza sul significato.
In poche parole un’architettura RESTful è di tipo client/server. I client fanno richieste ai server che a loro volta processano le richieste e restituiscono una risposta. Richieste e risposte contengono delle rappresentazioni di risorse. Una risorsa è un concetto significativo per il dominio di riferimento (ad esempio l’articolo di un blog o il profilo utente di un social network) che può essere identificato attraverso un indirizzo. Una rappresentazione è una descrizione dello stato corrente o voluto di una risorsa.
I vincoli dell’architettura
Lo stile architetturale REST descrive 6 vincoli (cinque più uno facoltativo) [1] che devono essere rispettati da un sistema affinche’ possa essere definito RESTful (Tabella 1). Poiche’ REST è uno stile e non una tecnologia e nemmeno una lista di raccomandazioni tecniche, i dettagli su come questi vincoli debbano essere implementati sono lasciati ai singoli sviluppatori. Ad esempio, l’Application Layer sul quale costruire il sistema non deve essere per forza HTTP, anche se HTTP è quasi sempre la scelta più naturale. Il formato delle rappresentazioni delle risorse spesso è XML o JSON, ma potrebbe essere anche PDF o, per i masochisti, un documento Microsoft Word. Infine REST non è uno stile architetturale solo per le web application, ma è molto più generale. Se i vincoli REST sono rispettati, l’architettura software di un robot (server) controllato da uno o più computer (client) dove le risorse sono l’hardware del robot (sensori e motori) può essere a tutti gli effetti considerata RESTful. Se il lettore fosse interessato, l’autore si è divertito in un lungo week end estivo a scrivere un piccolo framework RESTful per il suo robot Lego: http://www.github.com/mstn
Tabella 1 – Vincoli REST.
L’esperienza ha mostrato che sistemi RESTful hanno delle desiderabili proprietà emergenti, come ad esempio la scalabilità e la modificabilità. Anche la semplicità è una caratteristica desiderata in un’architettura RESTful e nel resto di questo articolo vorrei far capire la relazione tra la semplicità e lo stile REST e l’importanza che la semplicità ha nella progettazione di un sistema software. Il lettore che preferisce invece approfondire la comprensione del significato dei vincoli e degli altri elementi dello stile architetturale REST che non sono presi in considerazione in questo articolo può fare riferimento all’articolo di Wikipedia [1] o cercare sul web.
Semplice come bere un bicchier d’acqua
È un’impresa difficile capire il ruolo che la semplicità ricopre nei principi di ingegneria del software come qualità emergente di un sistema. Per questo non ho la pretesa di trattare l’argomento in modo definitivo e completo. Ma voglio comunque proporre alcune considerazioni personali maturate cercando di comprendere la filosofia di REST per meglio interpretarne lo stile nell’implementazione. Per quanto intuitivi possano sembrare i 6 vincoli, c’è sempre qualcosa di nuovo da imparare. Forse per REST vale la famosa frase di Richard Feynman pronunciata in merito alla meccanica quantistica: se credete di aver capito lo stile REST, allora vuol dire che non lo avete capito.
Nell’era dell’informazione è facile venire sommersi da quantità enormi di messaggi. Poiche’ l’attenzione è una risorsa scarsa, il rischio di perdersi e di perdere quello che veramente conta è una minaccia reale. La semplicità è quindi un valore da perseguire e la tecnologia può essere il mezzo per ottenere la semplicità dalla complessità del reale. In “The Laws of Simplicity” [4] John Maeda, professore del MIT, definisce delle linee guida per realizzare la semplicità in un prodotto tecnologico, dalle automobili di lusso all’iPod (Tabella 2). Gli stessi principi possono essere applicati per comprendere lo stile REST e il suo rapporto con la semplicità. Per motivi di tempo e spazio, ci focalizzeremo sulle prime tre leggi della semplicità che ci sembrano più adatte per descrivere lo stile REST. In un futuro articolo prenderemo in considerazione anche le altre.
Tabella 2 – Le dieci leggi della semplicità.
I: riduci
La prima legge di Maeda è “Riduci” e ha come motto “Il modo più semplice per conseguire la semplicità è attraverso una riduzione ragionata”. REST riduce la complessità restringendo l’insieme dei termini del vocabolario utilizzati per indicare azioni sulle risorse.
Nel protocollo HTTP sono definiti pochi verbi e i più usati sono GET, POST, PUT e DELETE. In modo analogo, molti servizi web definiscono di solito solo quattro azioni: CREATE, READ, UPDATE e DELETE. Lo stile non dice come si devono chiamare e quale deve essere il significato di queste azioni. Per essere RESTful occorre soltanto che l’interfaccia sia uniforme. Questa è una differenza con altri stili architetturali, come ad esempio SOA, dove non c’è nessun vincolo di uniformità sui metodi di un web service, ma il progettista è incoraggiato a definire ogni volta un nuovo e arbitrario vocabolario.
L’aspetto forse sorprendente di un’architettura RESTful è che quei pochi verbi molto spesso sono sufficienti per descrivere il comportamento di un sistema.
La complessità si riduce anche nascondendola. Un’architettura RESTful è un sistema client e server. L’interfaccia uniforme permette di nascondere le caratteristiche e i comportamenti del server al client e viceversa (SoC: Separation of Concern). In questo modo client e server possono svilupparsi in modo indipendente. In alcuni progetti a cui ho lavorato ho notato una confusione di fondo da parte delle persone coinvolte nella progettazione. Spesso si crede che il server sia la parte del sistema a cui è delegata la business logic mentre il client deve occuparsi solamente della presentazione dei dati. Non è sempre vero. In un’architettura RESTful il client può avere una business logic (ad esempio, filtrare gli elementi di una ricerca secondo criteri significativi solo per quel tipo di client). È sbagliato spostare questa logica tutta sul server perche’ viola la separazione di concern e crea una dipendenza tra client e server. Se non si nasconde la business logic del client al server, il sistema è meno scalabile e la complessità potrebbe diventare ingestibile con il passare del tempo e il rincorrersi delle modifiche.
Il vincolo sulle comunicazioni stateless tra client e server e il vincolo sulla struttura a livelli sono altri due precetti che lo stile REST impone per nascondere e ridurre la complessità.
L’ultima parte della prima legge della semplicità dice di incorporare, cioè far comprendere o percepire ad altri, la qualità di un prodotto. La qualità di un’architettura RESTful si manifesta nelle proprietà emergenti desiderate.
Però non sempre è facile comunicare il valore della semplicità ad altri. In un sistema complicato la complessità è visibile mentre in un sistema semplice la complessità è stata nascosta. L’errore che si commette è quello di credere che la gente apprezzerà di più il nostro lavoro se è messa nella condizione di vedere quanto lavoro è stato fatto. Un sistema complicato sembra richiedere più lavoro, ma in realtà sono necessari più sudore e più tempo per costruire un sistema semplice. Quindi un sistema semplice, anche di qualità, può essere paradossalmente percepito in modo negativo. C’è spesso difficoltà a progettare un’architettura RESTful quando si incontrano, ad esempio, management poco competenti e non in grado di comprenderne i vantaggi, oppure quando lo scopo del progetto non è il prodotto finale in se’, ma stupire con effetti speciali un particolare cliente.
II: organizza
La seconda legge di Maeda è “Organizza” e dice “l’organizzazione fa sì che un sistema composto da molti elementi appaia costituito da pochi”. In linea con la prima legge della semplicità, un’architettura RESTful ha un solo oggetto: la risorsa. Però un sistema composto da tanti elementi uguali può essere complesso da gestire. Quindi è opportuno organizzare le risorse in tipi di risorse e pensare a un meccanismo semplice e intuitivo per formare gli indirizzi che identificano le risorse.
Ad esempio, in un blog possiamo avere due tipi di risorse: post e comment. Gli indirizzi possono avere la forma
/{tipo di risorsa}/{id della risorsa}/{azione}
come in
/posts/1/edit oppure /posts/1/view
Non c’è una regola generale, anche se preferisco seguire queste linee guida (molto opinabili):
- usa pochi tipi di risorse;
- non organizzare i tipi di risorse per gerarchie;
- scegli i tipi di risorse tra concetti di basso livello, cioè pensa alla risorse come alle parole di una lingua, mentre frasi o concetti più complessi sono composti dal client secondo regole sue proprie.
L’organizzazione delle risorse in gruppi o tipi racconta qualcosa del sistema. Dice che cosa il sistema fa e soprattutto cosa non è. È importante evitare il proliferare di troppi tipi di risorse perche’ troppe risorse portano a complessità inutile e causano la mancanza di una visione unitaria e coerente del sistema. Questo può succedere quando il processo di progettazione risente dell’antipattern organizzativo denominato Design by Committee [5].
III: tempo
La terza legge è il “Tempo”: “i risparmi di tempo somigliano alla semplicità”. I client possono tenere traccia delle risposte (caching). Un buon meccanismo di caching permette di ridurre le interazioni tra client e server con ripercussioni positive sulla scalabilità e sulle performance del sistema. Lo stile REST non dice ovviamente come il meccanismo di caching debba essere implementato, ma è chiaro che è fondamentale anche per far percepire agli utenti la semplicità nell’esperienza d’uso del sistema.
Ad esempio, un’applicazione mobile che si interfaccia a dei servizi REST deve costruire un meccanismo di caching che tenga conto del fatto che la connettività potrebbe non essere sempre garantita. L’interazione dell’utente con l’interfaccia dell’applicazione non deve risentire dell’assenza di connettività e deve permettere all’utente di fare altro, in attesa della disponibilità dei dati richiesti.
Conclusioni
REST è uno stile di architettura che definisce dei principi di ingegneria del software. Questi principi derivano dall’esperienza avuta nella progettazione del Web e, se applicati correttamente, promettono di realizzare sistemi con delle caratteristiche desiderabili, ad esempio buone performance, scalabilità, modificabilità e via dicendo. In questo primo articolo si è cercato di spiegare come anche la ricerca della semplicità abbia giocato un ruolo fondamentale nell’identificazione e formalizzazione dello stile REST. In tal senso, si è visto come i vincoli REST siano in relazione con le prime tre leggi della semplicità formulate da John Maeda (riduci, organizza, tempo). La semplicità è un attributo fondamentale di ogni sistema software: di solito però non viene considerato come obiettivo da raggiungere nella progettazione di un sistema.
Riferimenti
[1] Voce “Representational State Transfer” su Wikipedia
[2] Roy Fielding, tesi di dottorato
[3] REST Discussion Mailing List
[4] John Maeda, “The Laws of Simplicity”, 2006, trad. it.”Le leggi della semplicità”, Bruno Mondadori, 2006
[5] Voce “Design by committee” su Wikipedia