Architetture REST: un modello di maturità

III parte: RESTful Web service e dintornidi

Con questo articolo terminiamo la serie dedicata a REST. Dopo aver presentato lo stile architetturale nel corso del primo articolo e aver eseguito un‘attenta comparazione tra integrazioni basate sullo stile REST e servizi Web service nel secondo, in questo terzo articolo investighiamo un‘interessante soluzione di compromesso: RESTful Web service. Proseguiamo ricapitolando l'importanza delle architetture multi-tiered soprattutto in contesti multi-channel e concludiamo presentando uno scenario ideale per lo stile REST tratto dal contesto enterprise.

Introduzione

Con questo articolo concludiamo la serie dedicata allo stile architetturale REST. Partiamo dalla presentazione del RESTful Web service, introdotto come importante compromesso tra Web service e REST. In particolare, questa soluzione permette di dar luogo a integrazioni che presentano parte dell'agilità e della leggerezza tipica REST, ma con governance e sicurezza propri dei Web service. Si prosegue con una breve discussione delle architetture multi-strato, mostrando come questa organizzazione, tra le altre cose, sia particolarmente vantaggiosa nei contesti multi-channel: è possibile risolvere problemi legati alla necessità di esporre la medesima business logic attraverso diversi protocolli senza toccare la business logic dell'applicazione. L'articolo si conclude con la presentazione di un esempio, attinto dal mondo enterprise, che rappresenta uno scenario ideale per lo stile REST. Si tratta di un'infrastruttura dati in cui la rappresentazione di dati come risorse è intrinseca nel codice del sistema.

RESTFul Web service

Nel corso dell'articolo precedente [2] abbiamo effettuato un'attenta comparazione tra integrazioni basate sullo stile REST e basate su Web services. Per gli scopi della trattazione, abbiamo volutamente sviluppato l'argomento come se queste due soluzioni fossero inconciliabili, evitando accuratamente le intersezioni. Ciò al fine di favorire una migliore comprensione "purista" dei pro e contro dello stile REST, utile per avere una chiara visione degli scenari ottimali per l'applicazione dello stile REST e di quelli in cui è meglio considerare attentamente questa alternativa. In realtà REST e Web service non sono poi fatalmente distanti: in questo paragrafo evidenziamo come sia possibile utilizzare soluzioni "ibride" disegnate per fornire un buon compromesso tra i due stili di integrazione.

Questione di Maiuscole

Prima di procedere oltre, tuttavia, è necessario chiarire un punto che, comprensibilmente, finisce per creare non poca confusione: RESTful web service non è la stessa cosa di RESTful Web service (si noti che la differenza risiede in come si scrive la prima lettera del termine web!).

Con il termine RESTful web service (web scritto in lettere minuscole), descritto in dettaglio nel primo articolo (cfr [1]), si indicano i servizi stateless invocabili esclusivamente attraverso il protocollo HTTP, univocamente identificati da un indirizzo globalmente univoco (URI), la cui rappresentazione delle risorse avviene per mezzo di un media type selezionato tra quelli supportati (testo, XML, JSON, etc.), che utilizza correttamente i verbi HTTP (GET, POST, PUT, etc.) per esporre operazioni CRUD delle risorse, e che ha una API hyperttext-driven. Su questo si è già parlato abbondantemente negli articoli precedenti e non è ulteriormente descritto in questo articolo.

Ciò che invece è di interesse per questo paragrafo è l'utilizzo di WSDL [3] (Web Service Description Language, linguaggio di descrizione dei Web Service) per i servizi REST. Da notare che i file WSDL possono essere immaginati, da un punto di vista concettuale, come l'equivalente della firma dei metodi. L'incontro tra REST e file .wsdl dà luogo ai RESTful Web service (Web scritto con la lettera maiuscola!). Per essere precisi ciò si è reso possibile solo grazie alla formulazione di WSDL 2.0 (Giugno 2007, cfr. [4]). Una delle principali linee guida di questa nuova versione è stata il pieno supporto dello stile REST. Ciò è chiaramente visibile dalle principali modifiche apportate (cfr. [4]) riassunte nella diagramma di figura 1.

 

 

Figura 1 - Principali elementi del WSDL 1.1. e WSDL 2.0.

 

L'incontro tra Web service e REST fa sì che sia possibile definire formalmente interfacce RESTful attraverso file WSDL. L'immediata logica conseguenza è che le integrazioni REST di questo tipo perdono parte della loro agilità e acquistano la governance tipica dei Web service. Ulteriori vantaggi derivano dal fatto di poter essere considerati a tutti gli effetti Web service, e quindi di poter godere di tutti i vantaggi che derivano dal maggiore grado di maturità. In particolare, come mostrato in figura 2, i RESTFul Web service presentano lo stesso livello di governance e di supporto tipico dei Web service. Per quanto attiene poi all'agilità, alla performance e alla security, queste si collocano in una posizione intermedia tra soluzioni pure REST e Web service. Ultimo elemento da considerare è la comunicazione. Da un punto di vista pratico tutti i Web service, e quindi anche quelli REST, potrebbero essere veicolati per mezzo di un sistema di messaggistica, ma questo rappresenterebbe una chiara violazione delle regole REST e pertanto non potrebbe considerarsi REST per definizione.

Da tener presente che i RESTful Web service non scalzano integrazioni RESTful tradizionali che continuano ad avere una loro importanza e precisi scenari di applicazione. In particolare, risultano ancora soluzione prioritaria in quei constesti in cui agilità e snellezza delle integrazioni sono caratteristiche fondamentali del sistema.

 

 

Figura 2 - Comparazione tra integrazioni pure REST, Web Service tradizionali e RESTful Web service.

 

Architetture multi-tiered

Il diagramma di figura 3 mostra un classico esempio di un'architettura multi-strato (multi-tiered) organizzata sui classici quattro strati: Presentation (presentazione), Business Logic (logica applicativa), Business Object (oggetti business) e Integration (integrazione). Questi sono descritti brevemente di seguito. Quello che è importante notare in questo contesto, è che questa struttura rende possibile esporre i servizi offerti dal sistema (per esempio ServiceA), forniti da componenti ubicati nello strato di business logic (ComponentA), attreverso diversi formati (per esempio, Web service, REST, JMS e CORBA) grazie ad opportuni componenti presenti nello strato di presentazione e alla segregazione di responsibilità derivata dai vari strati. Qui è necessario non confondersi: con il termine di presentazione non si fa riferimento esclusivamente alla GUI, bensì alla presentazione del sistema a tutti i suoi client, che si tratti di browser internet o un qualsivoglia sistema esterno.

A questo punto potrebbe sembrare che la diatriba Web service / REST sia in realtà fittizia: alla fine è sufficiente aggiungere opportuni componenti al livello di presentazione e il gioco è fatto. In realtà non è completamente così per una serie di motivi: vediamo di seguito quali sono quelli principali.

Disegno

Le direttive REST non riguardano esclusivamente lo strato di presentazione dei sistemi, ma anche un la "filosofia" alla base del sistema. Pertanto, qualora l'architettura non presenti un deciso orientamento verso le risorse, anche se si utilizzano il protocollo HTTP, i suoi vari verbi, etc., comunque il sistema e la relativa interfaccia non potrebbero fregiarsi del titolo RESTful. Inoltre è importante notare come la rappresentazione di un sistema in termini di risorse non è perfettamente allineata con lo stile SOA in cui l'enfasi è sui servizi. Interfacce di tipo GET, PUT, etc. non sono immediatamente riconducibili a servizi a livello business.

Ambiente di produzione

L'architettura multi strato senza ombra di dubbio fornisce notevoli vantaggi e non ci sono motivi per non organizzare i propri sistemi in base alle relative linee guida. Nel caso in questione, uno stesso servizio può essere esposto secondo i dettami di diversi protocolli senza doverne alterare l'implementazione. Tuttavia, un aspetto di notevole importanza spesso trascurato, è l'impatto che i sistemi hanno una volta messi in produzione, la loro sostenibilità, il loro costo totale, e così via. In questo caso è importante evidenziare come integrazioni basate su diversi protocolli (in qualche modo ridondanti) non solo devono essere implementate (richiedendo tempo e budget) ma devono anche essere gestite e fatte evolvere. Ciò significa, per esempio, approntare diversi meccanismi di monitoring per le varie integrazioni e gestire l'evoluzione controllata delle interfacce in modo ridondante. Questa parte non è sempre di immediata comprensione, ma il processo tipico per la realizzazione di una nuova versione dell'interfaccia, richiede che le stesse modifiche siano ripetute sulle varie integrazioni e che per un ben determinato intervallo temporale, il sistema supporti sia la versione precedente (per esempio ServiceA_v1.0) dell'interfaccia, sia la nuova versione (per esempio ServiceA_v2.0). Ciò, moltiplicato per il numero di ridondanze, genera un carico di lavoro non indifferente e un amento della complessità del sistema non trascurabile. Come al solito, la presenza di qualsiasi parte ridondante, incluse le interfacce, ha il suo costo e quindi va sempre ben ponderato.

 

 

Figura 3 - Schema di una classica architettura multi strato.

 

La conclusione è che le architetture multi-strato sono un must. Tuttavia, la possibilità di implementare diverse integrazioni ha un impatto sul TCO (Total Cost di Ownership, costo totale di possedimento) e pertanto l'implementazione di componenti ridondanti, specie al livello di interfacce, va ponderato accuratamente.

Nel dettaglio

Vediamo una breve spiegazione dell'architettura a strati mostrata in figura 3. L'idea base è che l'intera organizzazione dell'architettura del sistema sia risolta in una serie di strati organizzati in base a ben definite responsabilità (presentazione, business service, business object e integrazione). Si tratta di una serie di package software popolati da componenti dotati di specifiche interfacce, e quindi di ben definite dipendenze. Ogni layer fornisce specifici servizi allo strato immediatamente superiore utilizzando i servizi esposti dallo strato sottostante. Le uniche comunicazioni consentite sono quelle tra strati adiacenti. I vari strati presentano prestabilite interfacce (contratti tra strati) e la comunicazione avviene attraverso il passaggio di parametri che, tipicamente, assumono la forma di grafi di oggetti. Questi, in architetture Spring/JavaEE sono comunemente chiamati VO o DTO (Value Object o Data Transfer Object). La presenza di ben definite interfacce fornisce un livello di indirezione tra i vari strati e quindi permette di definire i vari strati in termini di package software self-contained che, come tali, si prestano ad essere sviluppati, verificati e mantenuti indipendentemente dagli altri.

In casi estremi, è anche possibile sostituire un intero strato con un altro, implementante le medesime interfacce, in modo assolutamente trasparente agli altri strati. Nella costruzione di sistemi software non è infrequente il caso in cui si dia luogo a un primo disegno, e quindi a una sua prima implementazione, non ottimizzato di alcuni componenti con l'intenzione di rivederne l'implementazione quando si avranno maggiori informazioni, o semplicemente quando si avrà maggiore tempo a disposizione.

 

In una architettura multi-strato, i diversi layer (strati) sono quelli che riportiamo di seguito.

Presentation

La "presentazione" è la principale interfaccia del sistema con i relativi attori esterni, sia umani sia sistemi client. Come tale ha la responsabilità di gestire la comunicazione tra gli attori del sistema, e il sistema stesso. In questo strato vi sono componenti che funzionano come Adapter/Fa�ade tra la business logic implementata dal sistema e gli attori esterni. Quini permetto di fruire i sistemi interni secondo le direttive dei diversi protocolli previsti.

Business service

I "servizi business" sono costituidi dai componenti allocati in questo strato: essi implementano i servizi offerti dal sistema. Nei processi formali, le operazioni fornite da questo strato sono ottenute direttamente dalle azioni (passi) specificate nei casi d'uso e dalle relative business rules.

Business object

Gli "oggetti business" costituiscono lo strato utilizzato per fornire i servizi di tipo CRUD su grafi di oggetti business. Le interfacce di questo strato sono derivate direttamente dal modello a oggetti del dominio prodotto durante la fase di analisi dei requisiti. Qualora di questi oggetti si effettui la persistenza su un database tradizionale, un grafo di oggetti, tipicamente, richiede l'interazione con diverse tabelle. I componenti di questo strato nascondo questi dettagli e fanno sì che le operazioni CRUD esposte risultino atomiche al livello dello specifico grafo a oggetti gestito dal particolare componente (per esempio il componente TradeBO implementa i servizi CRUD sul grado di oggetto Trade derivato dal modello ad oggetti del dominio).

Integration

Lo strato di "integrazione" è responsabile della gestione delle comunicazioni con dispositivi esterni sottostanti: gestisce l'accesso alle risorse come la base di dati e il sistema di messaggistica.

Servizi REST: un esempio ideale

Per poter discutere di questo esempio, è necessario effettuare una veloce incursione nel mondo delle architetture SOA (per maggiori dettagli cfr. [6]). Quando si disegnano architetture orientate ai servizi, si cerca di organizzare il sistema quanto più possibilmente in termini di self contained stateless macro-servizi (i cosiddetti coarse-grained service), possibilmente allineati ai servizi business, eventualmente vi si aggiunge un sistema di orchestrazione, e così via. Fin qui tutto abbastanza familiare: esiste tutta una letteratura dedicata all'argomento.

Un problema che invece è spesso trascurato è relativo alla condivisione dei dati tra le diverse applicazioni che offrono i vari servizi. Si tratta di un problema che investe diverse sfere: disponibilità dei dati nell'azienda, assicurazione del livello di qualità desiderato, infrastruttura necessaria per la relativa gestione ed efficiente condivisione, e così via. Tutti coloro che hanno lavorato in sistemi globali conoscono bene quanto sensibili e complesse siano queste problematiche. In questo contesto, tuttavia, si vuole focalizzare l'attenzione sull'infrastruttura (software) dati. L'esperienza insegna che è logico attendersi che all'interno di uno stesso dipartimento i vari servizi abbiano la necessità di condividere diverse tipologie di dati (almeno quelli"statici" o di riferimento). Pertanto, è necessario far sì che i diversi sistemi possano reperire i medesimi dati da un'opportuna infrastruttura dati, altrimenti realizzare sistemi SOA diventa un compito impossibile.

Si consideri per esempio, il servizio Pre-deal checking, ossia del controllo del rischio associato al cliente che si deve eseguire nell'area del front office delle investment bank prima di poter stipulare un Trade. A tal fine il sistema di front office esegue un'invocazione specificando i pochi dati necessari, come il codice univoco del cliente, l'ammontare del Trade, la moneta di riferimento, la tipologia del Trade etc. Ecco quindi che oltre ad assicurarsi che il servizio sia stato implementato rispettando le regole SOA è anche necessario che ci sia un totale accordo sui dati: il cliente X deve corrispondere alla stessa entità in entrambi i sistemi/servizi; inoltre è tipico che un sistema di rischio esegua calcoli diversi a seconda della tipologia del Trade. Pertanto, tra i vari sistemi, Front Office e Risk, deve esistere una perfetta sincronizzazione sulle tipologie di Trade, e così via. Ovviamente, ciò non vale solo per il sistema di front office e quello del calcolo del rischio associato al cliente, ma anche per tutti gli altri (enrichment e validation, settlment, reporting, etc). Ecco quindi che il problema di assicurarsi che i diversi sistemi condividano gli stessi dati di riferimento diviene un'esigenza assolutamente centrale e imprescindibile. Nasce la necessità di implementare un'infrastruttura dati, che si occupi di gestire i dati a partire dalla loro acquisizione fino alla fruizione e storicizzazione. Tale infrastruttura come evidenziato dalla figura 4, rappresenta un singolo punto logico per l'accesso ai dati (cfr [6]).

 

 

Figura 4 - Rappresentazione concettuale dell'infrastruttura dati.

 

L'implementazione di questa infrastruttura software è un contesto ideale per lo stile REST, per i motivi seguenti.

Orientamento alle risorse

In questo contesto l'orientamento alle risorse è intrinseco nella mission del sistema: il compito è infatti fornire servizi di accesso ai dati (CRUD di alto livello) rappresentato spesso da complessi grafi di oggetti. Dato il particolare contesto, è immediato comprendere la totale identificazione dei dati con le risorse. Esempi di dati gestiti sono: valute, strumenti finanziari, quotazioni, clienti, portafogli e trade.

Semplicità

I vari client possono integrare questo servizio direttamente e senza passi aggiuntivi, tipicamente richiesti da altri protocolli (come per esempio i web service). Inoltre, il funzionamento di questa infrastruttura può essere verificato per mezzo di un semplice browser commerciale. Ciò è particolarmente utile anche durante le fasi iniziali di implementazione dell'integrazione.

Comunicazioni sincrone

La fruizione dei servizi, a meno di casi particolari, è basato su protocolli sincroni di request/reply.

Performance

Le comunicazioni sincrone possono avvenire attraverso un'immediata connessione HTTP e lo stato delle risorse può essere trasmesso attraverso notazioni leggere come JSON.

Flessibilità

Questa infrastruttura può essere fatta evolvere, per esempio aggiungendo nuove tipologie di dati e quindi relativi servizi, senza dover cambiare le interfacce esistenti, cosa spesso richiesta da un'integrazione basata su web service.

Elevata agilità e time-to-market

Queste due caratteristiche sono una logica conseguenza di quanto descritto sopra.

Gli svantaggi

A fronte di questi vantaggi ci sono due potenziali svantaggi: sicurezza e governance.  In questo caso, queste proprietà non hanno un peso così determinante per via del fatto che si tratta di un'infrastruttura molto interna al sistema e quindi è possibile rilassare parzialmente (ma non rimuovere) requisiti di sicurezza e governance. Per quanto riguarda la sicurezza, per esempio, l'autenticazione del richiedente deve essere già avvenuta, è possibile delegare l'autorizzazione all'accesso ai dati; in caso sia veramente necessario poi è possibile ricorrere a una comunicazione HTTPS, e così via. Per quanto concerne la governance, il problema resta; tuttavia a parziale mitigazione interviene il fatto che lo stile REST impone l'implementazione di interfacce standard che in questo caso dà luogo a interfacce ben definibili a priori. Per esempio, una volta definita l'interfaccia per le valute, quella per le quotazione, per il clienti, per i trade etc. sono assolutamente identiche.

Riassumendo…

Con questo articolo concludiamo la serie dedicata allo stile REST. Si tratta di uno stile architetturale che nell'arco degli ultimi anni ha beneficiato di un notevole interesse da parte della comunità IT. La sua ideazione risale al 2000 e si deve alla tesi di dottorato di Roy Fielding intitolata "Architectural Styles and the Design of Network-based Software Architectures" ("Stili architetturali e disegno di architetture software basate sul networking"). Considerando che Fielding è uno dei principali autori di del protocollo HTTP, HypertText Transfer Protocol, ("protocollo di trasferimento degli ipertesti") versione 1.0 e 1.1 è abbastanza scontato che lo stile REST sia molto dipendente anche dai dettagli di questo protocollo.

Sebbene REST sia a tutti gli effetti uno stile, una filosofia architetturale, molta dell'attenzione, soprattutto in ambito enterprise è centrata sull'integrazione tra applicazioni. In questo contesto, REST si contraddistingue principalmente per la sua agilità e leggerezza. Questi vantaggi, come spesso avviene in informatica, vengono tuttavia attenuati dalla presenza di alcuni inevitabili svantaggi, che in questo caso sono la ridotta capacità di instaurare elevati livelli di governance e una maturità non ancora raggiunta pienamente.

Un elemento importante da considerare è che la filosofia REST e in particolare l'elevato focus sulle risorse non è sempre in linea con le direttive SOA che invece puntano di più sui servizi possibilmente allineati al business. Pertanto, sebbene un servizio del tipo place order si possa tranquillamente rappresentare come un POST su una risorsa Order (facendo contenti sia gli adepti SOA, sia quelli REST) lo stesso non è così immediato per altri servizi come per esempio il pre deal check e il calcolo del rischio del credit. Certo... si può fare, ma non è così pulito.

In questo articolo, abbiamo visto come sia possibile mitigare gli svantaggi delle integrazioni REST attraverso l'incontro con i Web service. In particolare, utilizzando un file WSDL 2.x, è possibile che le interfacce REST diventino a tutti gli esffetti Web service, più precisamente RESTful Web service. In questo modo, cedendo parte dell'agilità e delle snellezza tipica delle integrazioni REST è possibile ottenere sia la Governance tipica dei Web service, sia i vantaggi derivanti dalla relativa maturità. I RESTful Web service tuttavia non scalzano integrazioni RESTful tradizionali che continuano a avere una loro importanza in quei constesti in cui agilità e snellezza delle integrazioni sono caratteristiche fondamentali del sistema.

Altro elemento considerato è l'importante ruolo delle architetture multi-strato che anche in questo contesto forniscono ottimi vantaggi: permettono di presentare la stessa business logic attraverso diversi protocolli semplicemente aggiungendo opportuni componenti al livello di presentazione. Ciò tuttavia non avviene a costo zero, anzi. L'introduzione di componenti ridondanti comporta un aumento del TCO e della complessità del sistema. Pertanto, ogni decisione in questa direzione deve essere ben ponderata.

Per finire, l'articolo termina con la presentazione di uno scenario ideale per lo stile REST: l'implementazione di un'infrastruttura dati. In questo caso, non solo agilità e leggerezza sono driver fondamentali, ma vi è una totale aderenza tra il sistema e il concetto di risorsa.

 

Riferimenti

[1] Luca Vetti Tagliati, "Architetture REST: un modello di maturità - I parte: Da RESTless a RESTful", MokaByte 168, dicembre 2011

http://www2.mokabyte.it/cms/article.run?articleId=T5H-H8J-86C-DOC_7f000001_15042247_08e01d0b

 

[2] Luca Vetti Tagliati, "Architetture REST: un modello di maturità - II parte: I pro e i contro delle architetture REST", MokaByte 169, gennaio 2012

http://www2.mokabyte.it/cms/article.run?articleId=AGQ-1LC-4VI-EHG_7f000001_23585060_c13b3a46

 

[3] La voce "Web Service Description Language" su Wikipedia

http://en.wikipedia.org/wiki/Web_Services_Description_Language

 

[4] WSDL 2.0

http://www.w3.org/TR/wsdl20/

 

[5] W3C, Web Sevice Description Language

http://www.w3.org/TR/wsdl

 

[6] Luca Vetti Tagliati, "Java e le architetture a 64 bit: i puntatori compressi - II parte: Sfruttare i vantaggi in ottica SOA", MokaByte 158, gennaio 2011

http://www2.mokabyte.it/cms/article.run?permalink=mb158_java64bit-2

 

[7] Roy Thomas Fielding , "Architectural Styles and the Design of Network-based Software Architectures", PhD thesis, 2000

 

 

 

Condividi

Pubblicato nel numero
170 febbraio 2012
Luca Vetti Tagliati ha conseguito il PhD presso il Birkbeck College (University of London) e, negli anni, ha applicato la progettazione/programmazione OO, Component Based e SOA in diversi settori che variano dal mondo delle smart card a quello del trading bancario, prevalentemente in ambienti Java EE. Dopo aver lavorato a…
Articoli nella stessa serie
Ti potrebbe interessare anche