Il precedente articolo è stato dedicato alla presentazione dello stile architetturale REST. In particolare, sfruttando come esempio un ipotetico sistema universitario, abbiamo visto come farlo evolvere attraverso i vari livelli del modello di maturità di Richardson al fine di renderlo RESTful. In questo articolo continuiamo l‘analisi dello stile REST focalizzando l‘attenzione sui vantaggi e svantaggi nel contesto di architetture di medio-grandi dimensioni.
Introduzione
Nel corso dell’articolo precedente abbiamo presentato in dettaglio le direttive REST evidenziando importanti vantaggi di cui le singole applicazioni possono beneficiare soddisfacendo i cinque vincoli obbligatori REST [1] la cui applicazione rende i servizi RESTful. Dalla lettura del precedente articolo, dovrebbe essere ormai chiaro perche’ la quasi totalità della comunità IT concordi nel consigliare di disegnare e implementare applicazioni esposte a Internet/Intranet aziendale secondo le direttive REST; questo aspetto ormai dato per assodato non è ulteriormente trattato in questo articolo.
Oltre a fornire i vantaggi esposti nell’articolo precedente, l’applicazione delle direttive REST favorisce lo scambio di informazioni tra utenti. Per esempio è possibile inviare un’email ad un collega consigliando di leggere l’articolo [1], di acquistare il CD riportato in [9], di prenotare un posto su un determinato volo areo in modo da condividere un trasferimento [10] (ooops: nel momento in cui viene scritto il presente articolo, Expedia non segue le direttive REST).
Tuttavia, quando si estende il piano dell’analisi da singole applicazioni ad architetture di sistemi aziendali, la situazione cambia notevolmente ed è necessario ponderare attentamente il disegno architetturale in termini di servizi integrati (SOA). Ed è in questo contesto che l’architettura REST presenta alcuni limiti, tanto da limitarne i vantaggi a un insieme ben definito di casi d’uso. Come tipicamente accade, raramente esiste una soluzione universalmente valida: anche le direttive REST non sfuggono a questa regola, pertanto è opportuno conoscere in dettaglio gli scenari dove l’applicazione dello stile REST porta grandi vantaggi e quelli in cui la sua applicazione, almeno allo stato attuale, non è consigliata. Quando si parla di sistemi di medio-grandi dimensioni è necessario considerare accuratamente fattori quali il livello di accoppiamento tra servizi e quindi tra applicazioni, la governance dei servizi, il time-to-market, l’agilità e così via. Ed è proprio questo l’obiettivo dell’articolo che state leggendo: posizionare correttamente le architetture RESTful nel contesto di architetture di medio-grandi dimensioni focalizzando l’attenzione su un aspetto cruciale come l’integrazione tra sistemi. A tal fine questo articolo propone un parallelo con la principale alternativa ai “servizi REST”: i servizi esposti tramite protocollo Web Service. Da notare che ormai da diversi anni (cfr. [5], [6]) si studiano soluzioni atte a unire i vantaggi di questi due stili utilizzando il protocollo Web Service per la rappresentazione delle risorse veicolate attraverso messaggi REST. In questo caso si parla di RESTful Web Service. Questo argomento non è trattato esplicitamente in questo articolo, tuttavia la comparazione tra stile REST (con rappresentazione diversa da Web Service) e protocollo Web Service fornisce ottime basi per comprenderne le ragioni, le motivazioni e vantaggi dei RESTful Web Service.
Questa serie di articoli dedicati alle architetture REST terminerà con un ulteriore articolo nel quale si presenta un caso concreto di infrastruttura aziendale disegnata secondo le direttive REST. In quel contesto, inoltre, si dimostrerà ancora una volta l’importanza di implementare sistemi a strati (multi-tier).
Comunicazione
La prima feature investigata è la comunicazione e si parte con l’assegnare il primo punto a favore dei Web Service in quanto questo protocollo si presta ad essere fruito sia in modo sincrono per mezzo di invocazioni HTTP (Web Service over HTTP, HypertText Transfer Protocol, protocollo di trasferimento degli ipertesti), sia in modo asincrono per mezzo di infrastrutture basate su messaggi (per esempio Web Service over JMS). Le direttive REST, come si è avuto modo di illustrare nell’articolo precedente, sono fortemente ancorate al protocollo HTTP, il che è abbastanza ovvio considerando che il dominio delle ricerche di Fielding è il Web e che Fielding è stato uno dei principali autori di del protocollo HTTP versione 1.0 e 1.1 e ha iniziato la sua investigazione sui sistemi disponibili in Internet.
Comunicazioni sincrone
Le comunicazioni sincrone sono caratterizzate da un’applicazione client che invia una richiesta verso un fornitore di servizi e che quindi blocca il proprio thread chiamante fino alla ricezione della risposta. Pertanto, l’applicazione client può continuare la propria esecuzione (più precisamente può proseguire l’esecuzione del processo business che ha originato la necessità dell’interazione con il fornitore del servizio e quindi la chiamata) solo dopo aver ricevuto una risposta o un time-out. Per questo motivo, le comunicazioni sincrone sono anche definite bloccanti e come tali presentano un elevato grado di accoppiamento temporale tra le parti coinvolte nella comunicazione.
Qualora l’applicazione fornitrice del servizio non sia disponibile (per esempio sistema temporaneamente non disponibile per problemi tecnici oppure perche’ ha raggiunto il numero massimo di connessioni e quindi non è in grado di servire ulteriori richieste), l’invocazione dell’applicazione client riceve un’apposita notifica di errore e pertanto la corrispondente applicazione client deve farsi carico di gestire questo stato di errore. Un strategia spesso utilizzata per gestire problemi di questo tipo prevede che l’applicazione client avvii una serie di tentativi successivi, intervallati da appositi ritardi temporali. Questi tentativi terminano o quando si riesce ad ottenere il servizio voluto (per esempio una connessione si rende disponibile) oppure quando lo stato di errore perdura dopo aver eseguito tutti i tentativi previsti. La necessità di dover gestire la non disponibilità di un servizio, da un lato rende l’integrazione tra sistemi più complessa e ne incrementa il livello di accoppiamento, dall’altro però permette all’applicazione client di avere un maggiore controllo sul processo: l’applicazione client riceve un feedback immediato senza aver bisogno di implementare una logica dedicata per verificare lo stato della richiesta. Questa logica è invece necessaria in caso di comunicazioni asincrone, come illustrato di seguito.
Le comunicazioni sincrone, inoltre, presentano problemi di scalabilità che possono essere alleviati utilizzando soluzioni di load-balancing sia hardware, sia software. Alche il livello di agilità risulta ridotto quando le applicazioni sono integrate per mezzo di comunicazioni sincrone. Per esempio, la necessità di aggiornare un flusso business, tipicamente, genera un impatto sulle tutte le applicazioni integrate. Si consideri il caso che da uno scenario del tipo applicazione A integrata con applicazione B, si debba passare ad un caso più complesso in cui tra l’applicazione A e quella B sia necessario introdurre servizi offerti dall’applicazione C. In questo caso la modifica verosimilmente finisce per interessare tutte le applicazioni coinvolte. Tale necessità invece risulta molto ridotta in caso in cui la comunicazione avvenga in modo asincrono attraverso un sistema di messaggistica o meglio ancora per mezzo di un ESB. In questo caso, spesso è sufficiente modificare il flusso esternamente in modo spesso trasparente alle applicazioni.
La logica conclusione di questo paragrafo è che le comunicazioni sincrone, da un punto di vista architetturale, presentano una serie di svantaggi che bisogna considerare attentamente. Ciò ovviamente non significa che sia una pessima soluzione: esistono infatti scenari in cui questa integrazione presenta, al contrario, importanti vantaggi. È il caso di servizi gravati da SLA (Service Level Agreement) molto stringenti dal punto di vista della latenza oppure che richiedono un elevato grado di controllo. Un esempio classico è servizio Pre-Deal Check (controllo pre-trade) il quale ha la responsabilità di verificare che un nuovo trade rispetti tutta una serie di business rules che includono la gestione del rischio, il controllo del credito della controparte, l’applicazione delle regolamentazioni finanziarie e delle leggi del governo locale, e così via. Questo servizio deve essere espletato in millisecondi e l’applicazione client deve ricevere un feedback immediato. Pertanto, questo scenario rappresenta il caso ideale di integrazione sincrona.
La regola generale tuttavia è favorire comunicazioni asincrone qualora possibile, al fine di realizzare architetture di migliore qualità.
Comunicazioni asincrone
Le comunicazioni asincrone adottano un approccio noto con il nome fire and forget (letteralmente “spara e dimentica”, mutuato dall’industria bellica missilistica): l’applicazione client invia una richiesta (“spara”) e poi continua con la propria elaborazione ignorandone lo stato di avanzamento (“dimentica”). Pertanto, in questo caso il thread che ha avviato la richiesta non viene bloccato in attesa che il fornitore di servizio risponda alla richiesta asincrona. La logica conseguenza è che le applicazioni presentano un elevato grado di indipendenza temporale e quindi presentano un livello di accoppiamento minimo.
A fronte di questi vantaggi, l’applicazione client ha un ridotto livello di controllo: non riceve una notifica sincrona in caso di problemi. Per esempio, l’applicazione client pubblica un messaggio su una coda mentre il servizio fornitore non è disponibile. Sebbene questo sia un grandissimo vantaggio delle integrazioni sincrone, dall’altro è necessario creare una serie di meccanismi supplementari qualora l’applicazione client necessiti di monitorare l’andamento della propria richiesta. Si consideri per esempio il caso di un sistema client che invii in modo asincrono la richiesta di un mutuo di un cliente di una banca ad un altro sistema. Il sistema client in questo caso necessita di feedback, espliciti o impliciti. I meccanismi necessari per l’ottenimento del feedback possono prevedere sistemi di notifica da parte del servizio fornitore (evento inviato a ogni cambiamento di stato della richiesta), processi di time-out all’interno dell’applicazione client o di polling di un servizio che restituisca lo stato di avanzamento della richiesta. Da notare che lo scenario di richiesta di riscontro non è il più frequente.
Le comunicazioni asincrone sono tipicamente consigliate nei casi in cui è necessario ottenere un elevato throughput grazie all’elevata scalabilità intrinseca delle comunicazioni asincrone. Per esempio, se la comunicazione asincrona è basata su un’infrastruttura di messaggi, le applicazioni client possono inviare messaggi su code (o topic) prevedendo un numero congruo di processi “scodatori” (il numero di questi processi è tipicamente limitato dall’utilizzo di risorse condivise come il database) al lato dell’applicazione fornitore del servizio. Un elevato grado di scalabilità può essere raggiunto dimensionando opportunamente il numero delle code, il numero di richieste per messaggio (tipicamente si cerca di utilizzare un corretto livello di granularità dei vari messaggi raggruppandoli opportunamente in messaggi composti), il numero di istanze al lato dell’applicazione fornitrice di servizi e così via.
La strategia classica per implementare comunicazioni asincrone richiede l’utilizzo di un’opportuna infrastruttura: MOM (Message Oriented Middleware, implementazioni di JMS in caso Java), ESB (Enterprise Service Bus) etc. Queste, tipicamente, finiscono per fornire un elevato grado di agilità: diverse richieste di variazione di determinati flussi business possono essere risolti intervenendo direttamente sull’infrastruttura senza intaccare le varie applicazioni.
Le comunicazioni asincrone sono decisamente migliori da un punto di vista architetturale in quando riducono l’accoppiamento tra applicazioni, permettono una migliore scalabilità dell’intero sistema, favoriscono elevati throughput. Tuttavia non sono tipicamente la strategia ottimale per lo spazio della low-latency, sebbene da qualche anno sul mercato esistano soluzioni disegnate per risolvere questo problema in caso di comunicazioni asincrone: un prodotto leader in questo spazio è UMS (Ultra Messaging Streaming).
Comparazione tra comunicazione sincrone e asincrone
Di seguito riportiamo una serie di considerazioni schematiche per riassumere le differenze tra comunicazione sincrona e asincrona in rapporto alle diverse caratteristiche. Si tratta di un riassunto di quanto appena trattato.
Caratteristica: Accoppiamento temporale
Comunicazione sincrona: Elevato
L’applicazione client invia una richiesta a un fornitore di servizi e quindi blocca il proprio thread chiamante (e il processo business che ne ha originato tale richiesta) fino alla ricezione di una risposta o del un time-out. Nel caso di errore, l’applicazione client si deve far carico di intraprendere una determinata procedura per gestire tale stato.
Comunicazione asincrona: Ridotto
Le comunicazioni asincrone adottano l’approccio “fire and forget”: l’applicazione client invia una richiesta (“spara”) e poi continua con la propria elaborazione ignorando (“dimentica”) lo stato di avanzamento della propria richiesta. Il thread che ha avviato la richiesta non viene bloccato.
Caratteristica: Performance
Comunicazione sincrona: Low-Latency
Le comunicazioni sincrone sono tipicamente più idonee negli scenari caratterizzati da richieste di tempi di risposta ridottissimi.
Comunicazione asincrona: High-Throughput
Integrazioni asincrone tipicamente forniscono migliori prestazioni nello spazio di throughput elevati.
Caratteristica: Scalabilità
Comunicazione sincrona: Ridotta
I fornitori di servizi tendono ad avere una capacità di carico (numero massimo di connessioni) limitata. L’unico modo per consentire a questi sistemi di aumentare il proprio grado di scalabilità consiste nel creare un adeguato cluster e di ricorrere a opportuni meccanismi di load-balancing.
Comunicazione asincrona: Elevata
I sistemi asincroni presentano un grado intrinseco di scalabilità molto elevato. Questo sopratutto grazie al ricorso a infrastrutture quali sistemi di messaggi che permettono di incrementare il livello di scalabilità attraverso l’aggiunta di ulteriori code e processi “subscriber”.
Caratteristica: Agilità
Comunicazione sincrona: Ridotta
Variazioni dei processi business (per esempio diversa sequenza dei passi richiesti) tendono a ripercuotersi sulle applicazioni integrate in modo sincrono.
Comunicazione asincrona: Elevata
Molte variazioni dei processi business possono essere neutralizzate da opportune variazioni del middleware e quindi sono trasparenti alle varie applicazioni coinvolte.
Caratteristica: Controllo
Comunicazione sincrona: Elevato
L’applicazione client ottiene un feedback immediato e quindi può decidere istantaneamente quali procedure intraprendere.
Comunicazione asincrona: Ridotta
La strategia alla base di questa comunicazione è “fire & forget”. Pertanto l’applicazione client, una volta inviata la richiesta, ne perde il controllo. Qualora abbia bisogno di seguirne l’evoluzione, è necessario implementare meccanismi sofisticati come invio di notifiche, time-out interni, polling, etc.
Caratteristica: Complessità
Comunicazione sincrona: Elevata
La gestione di situazioni anomale (sempre necessaria) aumenta la complessità delle comunicazioni sincrone.
Comunicazione asincrona: Ridotta
Nei scenari classici la complessità di queste soluzioni è molto limitata. Tuttavia aumenta nel caso in cui i client abbiano bisogno di informazioni relative all’evoluzione delle proprie richieste.
Caratteristica: Supporto transazionale
Comunicazione sincrona: Non supportato
Il supporto transazionale non è supportato.
Comunicazione asincrona: Supportato
Questo supporto è dato dall’infrastruttura di messaggi.
Un aspetto fondamentale: la governance
Vediamo adesso un altro aspetto importante. Lo stile REST, come visto nel capitolo precedente, detta l’utilizzo di interfacce uniformi e implicite basate sui verbi standard del protocollo HTTP [1]. Sebbene da un lato le interfacce implicite uniformi offrano tutta una serie di vantaggi come per esempio, il significativo aumento della flessibilità (e quindi dell’agilità) ed un’automatica elevata consistenza tra interfacce, dall’altro ciò rende la governance più complessa e meno efficace nel contesto di architetture complesse. In particolare, una pianificazione accurata dell’evoluzione di sistemi di medio-grandi dimensioni formati da molteplici applicazioni, che offrono centinaia/migliaia di servizi spesso gestiti da diversi team dislocati geograficamente, impone che i vari servizi evolvano in maniera strutturata. Ciò implica che i servizi debbano essere disegnati seguendo gli standard aziendali e della comunità IT, seguano le best practice disponibili, siano documentati correttamente, che le interfacce siano consistenti (sia relativamente a un modello di business condiviso, sia in merito alla struttura e ai tipi di dati utilizzati), che le ridondanze siano ridotte al minimo (per esempio invece di realizzare diverse interfacce con un elevato grado di similarità è preferibile realizzarne una più generica), che ci sia un processo molto chiaro per la gestione del disegno e dell’aggiornamento dei vari servizi. Questa serie di attività viene comunemente indicata con il termine Governance. La governance è un processo fondamentale soprattutto nel contesto di architetture SOA al fine di assicurarsi che i molteplici servizi evolvano in maniera organica evitando di finire in un totale stato di perdita di controllo che renderebbe l’architettura ingovernabile.
Anne Thomas Manes [2] definisce la governance come “il processo che le aziende creano/adottano per assicurarsi che determinate attività siano svolte secondo le best practices, i principi architetturali, le politiche aziendali, le leggi in vingore e altri importanti fattori. La Governance nel contesto SOA si riferisce al processo utilizzato per governare l’utilizzo e le implementazione di sistemi SOA”.
I Web Service sono definiti per mezzo del linguaggio WSDL [3] (Web Service Description Langauge, linguaggio di descrizione dei Web Service) che attraverso la notazione XML permette di definire accuratamente i servizi (si tratta dell’equivalente della firma dei metodi). I file WSDL si prestano a essere documentati accuratamente e a essere memorizzati in appostiti repository (service registry). Questi semplici elementi favoriscono enormemente la definizione della relativa governance. Per esempio, è possibile sia prevedere un team addetto alla supervisione dei servizi, sia definire un processo di interazione tra gli architetti responsabili dei singoli servizi ed il team si supervisione. Questo processo potrebbe prevedere la negoziazione tra l’architetto e il team per la creazione di nuovi servizi, la modifica di quelli esistenti, l’obbligo della revisione del disegno dei servizi prima della loro memorizzazione nel service registry, l’obbligo della registrazione dei servizi per permetterne il deployment, e così via.
Secondo Thomas Erl, uno dei principi fondamentali del disegno di architetture a servizi è il principio del Service Discoverability [4]: “La scoperta dei servizi è il fondamentale processo di scoperta durante il quale gli umani individuano un potenziale servizio accedendo al service registry che rappresenta l’inventario dei servizi per poi interpretarne il servizio al fine di determinarne l’idoneità”.
Non è a caso che, per cercare di individuare un buon compromesso tra l’agilità delle linee guida REST e la governance Web Service, è da qualche anno che si discute di RESTful Web Services [5], [6].
Supporto: a che punto siamo?
È un dato di fatto che lo stile REST nel corso degli ultimi anni abbia ricevuto una grande attenzione da parte della comunità informatica, soprattutto tra gli adepti Java. Questo è evidente da molteplici fattori, come il numero di framework sviluppati per semplificare la creazione di architetture RESTful, dal fatto che sia Spring 3.0 (MVC Spring definisce URI secondo le direttive REST), sia Java EE 6 (JSR 311: JAX-RS [7]) prevedono delle annotazioni specifiche per semplificare l’implementazione di architetture RESTful. Per esempio, Java EE 6 include l’annotazione @Path per eseguire il mapping tra un determinato URI con una “risorsa REST”. Quest’ultima è una normale classe Java (POJO), la quale ha almeno un metodo annotato con @Path (o un’annotazione a runtime @HttpMethod denominata request method designator). In questo modo la risorsa può essere esposta al Web. A tal fine è possibile utilizzare le annotazioni @GET, @PUT, @POST e @DELETE per indicare che corrispondenti metodi implementano i “verbi” standard HTTP get, put, post e delete.
Detto ciò è altrettanto evidente che il supporto per le architetture REST non è ancora ad un livello paragonabile a quello dei Web Service. Questo si evince da diverse constatazioni incluso il grande lavoro svolto relativo alle performance e sicurezza. Inoltre, la quasi totalità delle nuove infrastrutture e tool prevedono nativamente servizi esposti come web service. La Microsoft ha selezionato i web service come fondamento del Microsoft’s interoperability model.
Una proprietà interessante: agilità
Una delle proprietà più interessanti dello stile REST è legata alle interfacce uniformi implicite basate sulle risorse (cfr. [1]) ed esposte attraverso i “verbi” standard HTTP. Questa proprietà genera tutta una serie di importanti vantaggi, come per esempio la possibilità di investigare/verificare un servizio RESTful a partire da un semplice web browser commerciale e di integrare e sviluppare servizi RESTful rapidamente senza passi intermedi. Inoltre, diverse estensioni del servizio (in funzione anche della notazione selezionata per la rappresentazione dello stato delle risorse) possono avvenire in maniera trasparente per le applicazioni client , a patto, ovviamente, che non vengano modificate le strutture di loro interesse. In poche parole, ciò significa che i servizi RESTful presentano un elevato grado di flessibilità e quindi un ridotto time-to-market. Tuttavia, questo elevato grado di flessibilità è limitato dal fatto che le comunicazioni possano avvenire solo in modo sincrono.
D’altro canto i Web Service presentano un’agilità ridotta essenzialmente limitata alla struttura del messaggio XML e alla presenza di oculati punti di estensione (XML abstract, substitutionGroup, etc.). I client sono tipicamente esposti a ogni cambiamento anche minimo e di non interesse della struttura dati utilizzata. Questo essenzialmente perche’ ogni variazione anche minima richiede la generazione di un nuovo file WSDL. Infine, l’esplorazione di servizi Web Service è tutt’altro che immediata.
Il delicato tasto delle prestazioni: performance
Discutere di performance è sempre abbastanza complicato per via dei molteplici fattori che intervengono a influenzare le varie analisi. Per esempio, nel caso in questione, le performance sono influenzate da tutta una serie di elementi, come per esempio la notazione utilizzata per la rappresentazione dello stato della risorsa REST, la struttura e l’organizzazione dei messaggi, la possibilità di verifica dello schema, e così via. Inoltre, come visto in precedenza, mentre servizi RESTful sono relegati alle sole comunicazioni sincrone via HTTP/S, i Web Service possono essere anche veicolati in modo asincrono.
Detto ciò, limitando l’attenzione alle comunicazioni sincrone, è abbastanza accettato che i servizi REST tendono a essere più snelli e quindi più veloci da fruire. Inoltre, il protocollo HTTP include tutta una serie di meta-informazioni nello header (cfr. [1]) a uso e consumo di eventuali nodi intermedi per la gestione di cache locali. Questo può far sì che diverse richieste possano essere risolte senza neanche raggiungere il server che fornisce il servizio richiesto. Tuttavia, la presenza di interfacce uniformi basate sulle risorse fa sì che non sia consentito implementare particolari interfacce atte ad ottimizzare specifiche richieste.
Per quanto concerne i Web Service, sebbene molto lavoro sia stato fatto sulla notazione XML e sugli stessi Web Service, tipicamente, non possono essere considerati la soluzione in grado di offrire le performance migliori. Molto dipende naturalmente anche da come sono implementati i vari schemi XML, dal mapping degli oggetti, e così via. Tuttavia, i Web Service offrono il vantaggio di poter disegnare interfacce ad-hoc per risolvere specifici problemi di performance ed inoltre è sempre possibile utilizzare soluzioni hardware per accelerare la gestione della notazione XML.
Proteggere la propria architettura: sicurezza
Il protocollo Web Service/SOAP da diversi anni è considerato una sorta di standard de-facto di integrazione, questo ha fatto sì che diversi gruppi abbiamo studiato e messo a punto soluzioni per i diversi aspetti dei Web Service inclusa la sicurezza. OASIS (Advancing Open Standards for Information Society, [7]) ha da tempo definito le direttive WSS (Web Service Security) incorporate dal framework Java XWS-Security [8]. In particolare, WSS definisce un’estensione standard SOAP disegnata per fornire un’elevata protezione attraverso l’integrità del messaggio, la riservatezza e l’autenticazione dei messaggi. I meccanismi WSS possono essere usati per ospitare una grande varietà di modelli di sicurezza e tecnologie di crittografia. La specifica WSS definisce un framework che copre tutti gli aspetti della sicurezza incluso il supporto per l’elaborazione intermedia. L’integrità del messaggio è fornita utilizzando la firma XML (XML digital signature), in collaborazione con i token di sicurezza per garantire che i messaggi siano trasmessi senza modifiche. La riservatezza dei messaggi è ottenuta utilizzando XML Encryption in collaborazione con token di sicurezza per mantenere porzioni di messaggi SOAP confidenziali.
Per quanto concerne lo stile REST, sebbene diversi gruppi stiano lavorando ad una serie di soluzioni, queste sono ancora non standard e pertanto l’aspetto della sicurezza per i servizi REST è essenzialmente delegata alla sicurezza di canale, ossia all’utilizzo del protocollo HTTPS.
I vincoli di costi e tempi: budget/time
Da quanto emerso dalle feature riportate nei paragrafi precedenti, dovrebbe risultare chiaro che i servizi RESTful richiedono un investimento iniziale limitato soprattutto nei contesti in cui il numero di sistemi esistenti è limitato. Tuttavia, nel contesto oggetto di analisi ossia quello enterprise, la difficoltà di dar luogo a una vera e propria governance e la limitazione alle sole comunicazioni sincrone, fa sì che un utilizzo massiccio di questa soluzione tenda a richiedere un TCO (Total Cost of Ownership) elevato.
I Web Service presentano uno spettro completamente speculare in cui gli investimenti iniziali sono spesso importanti e tendono ad essere un elemento critico in scenari piuttosto semplici. Tuttavia, questi investimenti tendono a essere ammortizzati con il tempo e a offire un migliore TCO a medio-lungo termine.
Come è legittimo attendersi, una buona soluzione consiste nel dar luogo ad un accurato mix delle due soluzioni.
Sommario della comparazione Web Service vs. REST
Anche in questo caso forniamo un sommario in cui lo stile REST viene messo a confronto con lo stile Web Services sulla base di particolari caratteristiche.
Caratteristica: Comunicazione
REST: Limitata al caso sincrono
Lo stile REST è legato a doppio nodo al protocollo HTTP. Pertanto l’unica comunicazione supportata è quella sincrona.
Web Service: Estesa a entrambe le modalità
Le comunicazioni Web Service possono avvenire attraverso il protocollo HTTP (questa è sicuramente la modalità più nota), ma anche attraverso invocazioni asincrone come per esempio Web Service over JMS.
Caratteristica: Governance
REST: Ridotta
Le interfacce REST sono uniformi e implicite. Ciò è un grande vantaggio da diversi punti di vista, ma limita fortemente la possibilità di instaurare opportuni livelli di governance.
Web Service: Elevata
Stabilire la governance di servizi esposti attraverso Web Service è abbastanza immediato grazie anche alla presenza di interfacce esplicite (WSDL), ben documentabili, memorizzabili in appositi registry.
Caratteristica: Supporto
REST: Medio
Lo stile REST sta ottenendo sempre maggiore attenzione da parte della comunità IT e ciò si ripercuote sia sui framework disponibili sia sulle infrastrutture che ne prevedono l’adozione. Tuttavia ancora non si è giunti al livello di supporto offerto dai Web Service.
Web Service: Elevato
È ormai da diversi anni che i Web Service hanno raggiunto l’apice della popolarità, tanto da essere considerati uno standard de facto per quanto attiene l’integrazione di sistemi. Questo elevato livello di maturità si riflette sul livello di supporto: la quasi totalità di prodotti, applicativi e framework prevede integrazioni basate sui Web Service.
Caratteristica: Agilità
REST: Elevata
Le interfacce sono uniformi e definite implicitamente quindi la loro implementazione/modifica è immediata. Inoltre, è possibile eseguire tutta una serie di estensioni al lato server in modo pressoche’ trasparente per i client. Connettere nuovi client a fornitori di servizi RESTful è immediato e non richiede particolari passaggi intermedi. I servizi RESTful possono essere esplorati e verificati per mezzo di un semplice browser commerciale.
Web Service: Ridotta
La flessibilità dei servizi Web Service è quasi interamente demandata al disegno della struttura XML. Per esempio, si possono prevedere opportuni punti astratti che è possibile estendere in futuro. Per il resto, i Web Service sono uno strumento formale e come tale sia l’aggiornamento, sia l’utilizzo richiedono una serie di passaggi intermedi. L’estensione dei servizi Web Service ha un impatto sui client.
Caratteristica: Performance
Dipende da molti fattori.
REST: Medio-Elevate.
Le interfacce dei servizi RESTful sono tipicamente molto snelle e veloci da manipolare. Inoltre il protocollo HTTP prevede delle meta-informazioni per consentire a nodi intermedi di gestire cache locali. Ciò può far sì che diverse richieste possano essere soddisfatte senza neanche giungere al server. Come lato negativo, non è possibile disegnare interfacce particolari non basate sulle risorse per ottimizzare specifici problemi di performance.
Web Service: Medie.
La performance dei Web Service è vincolata a diversi fattori e soprattutto all’utilizzo della notazione XML. Tipicamente i messaggi scambiati non sono i migliori in termini di performance. Tuttavia, è possibile disegnare delle interfacce adhoc per risolvere specifici problemi di performance ed è sempre possibile ricorrere a soluzioni hardware per accelerare la manipolazione dei formati XML.
Caratteristica: Security
REST: Limitata
Sebbene diversi gruppi stiano lavorando a diverse soluzioni e alcune non standard siano già disponibili, allo stato attuale il principale meccanismo di sicurezza utilizzato in integrazioni REST è legato al canale, ossia all’utilizzo del protocollo HTTPS.
Web Service: Estesa
I Web Service sono lo standard de facto da diversi anni e pertanto è possibile trovare tutta una serie di soluzioni di sicurezza standard. In particolare, OASIS ha definito il framework WSS (Web Service Security) che definisce un’estensione standard SOAP disegnata per fornire un’elevata protezione attraverso l’integrità del messaggio, la riservatezza e l’autenticazione dei messaggi.
Caratteristica: Time/Budget
REST: Medio, migliore in scenari più semplici
I servizi RESTful richiedono un investimento iniziale limitato e sono ottimali in scenari semplici. La difficoltà di dar luogo ad una vera propria governance e la limitazione alle sole comunicazioni sincrone, fa sì che in contesti enterprise l’utilizzo esclusivo di soluzioni REST richieda maggiori investimenti e renda il sistema più complesso e quindi costoso da gestire.
Web Service: Medio, migliore in scenari più complessi
Le soluzioni Web Service tendono a richiedere maggiori investimenti iniziali. Spesso l’utilizzo per semplici scenari richiede un overhead non trascurabile. Tuttavia, in contesti meno immediati, tipici delle enterprise, gli investimenti iniziali tendono ad essere abbondantemente ammortizzati a medio-lungo termine.
Figura 1 – Diagramma concettuale di comparazione tra REST e Web Service.
Conclusioni
In questo secondo articolo abbiamo analizzato in dettaglio le caratteristiche dello stile REST dal punto di vista dell’integrazione confrontandolo con il protocollo Web Service che viene considerato la principale alternativa. La trattazione è stata sviluppata dal punto di vista del dominio enterprise (la trattazione di un contesto formato solo da qualche applicazione è decisamente poco interessante e non permette di considerare elementi critici). Inoltre, si è considerato il caso in cui la rappresentazione dello stato della risorsa inclusa nei messaggi REST sia realizzata da un protocollo diverso da Web Service. La fusione tra i due stili, ossia rappresentazioni Web Service inclusi in messaggi REST (i RESTful Web Service) non sono oggetto di questo articolo. Questo sia per far comprendere appieno le caratteristiche dello stile REST “senza contaminazioni” soprattutto dal punto di vista dell’integrazione, sia per far maggiormente apprezzare i vantaggi che si possono conseguire dall’incontro di questi due stili.
In questo articolo inoltre non siamo entrati nel dettaglio delle applicazioni esposte ad Internet/Intranet aziendale: quasi l’unanimità della comunità IT riconosce i vantaggi dello stile REST applicato al dominio web e non vi sono grandi effetti collaterali. Una situazione ben diversa invece è rappresentata dai servizi, per così dire, più interni alle architetture aziendali. In questi casi è necessario ponderare attentamente l’utilizzo dello stile REST. Il diagramma di figura 1 mostra chiaramente la diversa configurazione dei servizi REST rispetto ai Web Service: i primi brillano dal punto dell’agilità e (con le dovute cautele) performance mentre i secondi presentano un aspetto decisamente più proteso verso la formalità (governance e supporto) e quindi che si presta maggiormente ad un contesto enterprise. Ciò tuttavia non suggerisce affatto di progettare architetture basate solo su Web Service, ma di valutare attentamente le caratteristiche del particolare servizio per stabilire, di volta in volta, lo stile più appropriato. Lo scenario tipico di architetture complesse basate su molteplici servizi prevede un accurato mix di soluzioni.
Nel selezionare lo stile più idoneo, è necessario valutare diversi fattori. Uno di questi è la comunicazione asincrona. Qualora un servizio sia fruibile in modo asincrono è opportuno favorire questa modalità di comunicazione in quanto favorisce l’evoluzione architetturale. Quindi in questo caso REST potrebbe non rappresentare una delle soluzioni più appropriate. Un altro fattore è il livello dell’interfaccia. Più un interfaccia è pubblica (per esempio interfacce tra diversi dipartimenti) e maggiore è il livello di governance richiesto e pertanto il protocollo Web Service presenta caratteristiche più conformi. Un ulteriore fattore è l’estensibilità del servizio. Qualora un servizio debba essere esteso nel tempo, soprattutto in modo orizzontale (aggiunta di nuove strutture) e utilizzato prevalentemente da servizi “interni”, allora lo stile REST è probabilmente molto consigliato.
Come al solito, il lavoro dell’architetto consiste nel riuscire ad individuare la soluzione più idonea per le specifiche caratteristiche attuali e future.
Riferimenti
[1] Luca Vetti Tagliati, “Architetture REST: un modello di maturità – I parte: Da RESTless a RESTful”, MokaByte 168 – Dicembre 2011
[2] Anne Thomas Manes, “The Elephant Has Left The Building”, 1 July 2005
[3] W3C, Web Sevice Description Language
[4] Thomas Erl, Service Discoverability service
http://soapatterns.org/metadata_centralization.php
[5] Leonard Richardson, Sam Ruby, “RESTful Web Services, Web Services for the real world”, O’Reilly, 2007
[6] Jose’ Sandoval “RESTful Java Web Services”, Packt Publishing, 2009
[7] JAX-RS: Java API for RESTful Web Services, Version 1,1 17 Settembre 2009
[8] OASIS Web Services Security (WSS) TC
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss
[9] The Best Of Vaya Con Dios
http://www.amazon.co.uk/Best-Vaya-Dios/dp/B0000075TY/ref=sr_1_3?ie=UTF8&qid=1323627006&sr=8-3
[10] Travel cheaper with Expedia!
https://www.expedia.co.uk/pub/agent.dll