Introduzione a REST

I

introduzione

Se sei uno sviluppatore Web avrai sentito sicuramente parlare di Web Service Restful come alternativa ad altre specifiche di computing distribuito, come SOAP. Ma cos’è REST davvero? C’è molta confusione in giro, cerchiamo brevemente di definirlo non focalizzandoci su una sua possibile implementazione ma sui suoi principi.

Representational State Transfer (REST)

Voglio andare controtendenza e partire da cosa non è Rest, andando a smascherare falsi miti e le false voci che si sentono in giro.

NON E’ UN PROTOCOLLO

Un protocollo di solito descrive i messaggi esatti (o parti di essi) che i due (o più) attori devono scambiare. Specificare anche la coreografia su come vengono scambiati questi messaggi e cosa significano. Uno stile architetturale (come REST) non descrive affatto i messaggi, ma specifica i requisiti (vincoli architetturali) che i messaggi, la coreografia o parti del sistema devono soddisfare.

NON E’ UNa specifica

A differenza dei servizi Web basati su SOAP, non esiste uno standard “ufficiale” per le API Web RESTful. Questo perché REST è uno stile architetturale, mentre SOAP è un protocollo. REST non è uno standard in sé, ma le implementazioni REST fanno uso di standard, come HTTP, URI, JSON e XML. Molti sviluppatori descrivono anche le proprie API come RESTful, anche se queste API in realtà non soddisfano tutti i vincoli architetturali previsti da REST.

NON E’ PER FORZA LEGATO AD HTTP

Una cosa che confonde le persone, è che REST e HTTP sembrano essere la medesima cosa. Dopotutto, il world wide web funziona su HTTP, e ha senso, l’API RESTful fa lo stesso. Tuttavia, non c’è nulla nei vincoli REST che rende obbligatorio l’uso di HTTP come protocollo di trasferimento. È perfettamente possibile utilizzare altri protocolli di trasferimento come SNMP, SMTP e altri.

QUINDI CHE COS’E’ ?

L’espressione “representational state transfer” e il suo acronimo “REST” furono introdotti nel 2000 nella tesi di dottorato di Roy Fielding, uno dei principali autori delle specifiche dell’Hypertext Transfer Protocol (HTTP). Roy Fielding descrive il Representational State Transfer come uno stile architetturale (“architectural style”), ovvero un’astrazione degli elementi di un’architettura all’interno di un sistema hypermedia distribuito. REST ignora i dettagli dell’implementazione dei componenti e della sintassi del protocollo al fine di concentrarsi sui ruoli dei componenti, i vincoli sulla loro interazione con altri componenti e la loro interpretazione. Ci tengo ancora una volta a dire che è molto importante capire la differenza tra un architettura e protocollo: mentre un protocollo potrebbe specificare: “usa JSON nel seguente formato per richiedere un preventivo”. Uno stile architetturale dice semplicemente: “i client possono contattare i server, ma non il contrario”. È un livello di astrazione completamente diverso.

Basta filosofeggiare! Abbiamo detto tutto quello che non è REST, abbiamo detto che è uno stile architetturale: un’astrazione degli elementi di un’architettura costruita su dei principi descritti a fondo nella tesi di Roy Fielding.  Ma quali sono questi principi che costituiscono una architettura REST?

 

PRINCIPI E VINCOLI DI REST

Riassumiamo i principi che deve rispettare una architettura REST.

 

1. Client-Server

Una architettura REST sposa il noto paradigma dell’informatica conosciuto con il termine di separation of concerns (SoC) : tradotto in italiano come “separazione delle preoccupazioni o compiti“. SoC è un principio di progettazione per separare un sistema in moduli distinti, in modo tale che ogni modulo si preoccupi di un certo compito.

REST applica il paradigma SoC con un architettura Client-Server . Ciò aiuta a stabilire un’architettura distribuita, supportando in tal modo l’evoluzione indipendente della logica lato client e della logica lato server.

Il vincolo Client-Server richiede che il server offra una o più funzionalità e ascolti le richieste di possibili client. Un client invoca il servizio messo a disposizione dal server inviando il corrispondente messaggio di richiesta e il servizio lato server respinge la richiesta o esegue l’attività richiesta prima di inviare un messaggio di risposta al client. La gestione delle eccezioni è delegata al client.

2. stateless

La comunicazione tra utente del servizio (client) e servizio (server) deve essere senza stato tra le richieste. Ciò significa che ogni richiesta da parte di un client dovrebbe contenere tutte le informazioni necessarie per il servizio per comprendere il significato della richiesta. Tutti i dati sullo stato della sessione dovrebbero quindi essere restituiti al consumatore del servizio alla fine di ciascuna richiesta. In breve ogni richiesta è come se fosse la prima richiesta e non è correlata ad una precedente richiesta.

Se il server è senza stato, può scalare molto più facilmente e sicuramente sarà molto più semplice perché elimina alla radice il problema della gestione e sincronizzazione delle sessioni utente in ambienti clusterizzati. Facciamo un esempio: il tuo servizio REST è utilizzato da milioni di persone e non regge il carico? Essendo stateless potrà essere scalato orizzontalmente in maniera semplicissima: basterà tirare su più istanze del tuo servizio  bilanciando il carico. Come? Utilizzando un Load Balancer che si ponga davanti alle istanze dei nostri server e passi le richieste seguendo delle regole ben precise (ad esempio, con l’algoritmo round robin a turno ogni server riceverà una richiesta, giunti all’ultimo server si riprende l’assegnazione partendo dal primo).

3. CACHE

Parto a descrivere questa proprietà dei sistemi REST con una citazione molto nota nel WEB

La richiesta di rete più efficiente è quella che non utilizza la rete.

in un Architettura REST i messaggi di risposta dal servizio ai suoi consumatori sono esplicitamente etichettati come cachabili o non. In questo modo, il servizio, il consumatore o uno dei componenti middleware intermediari possono memorizzare nella cache la risposta per il riutilizzo nelle richieste successive.

Il vincolo Cache si basa su Client-Server e Stateless con il requisito che le risposte siano etichettate implicitamente o esplicitamente come memorizzabili nella cache o non memorizzabili nella cache. Le richieste vengono passate attraverso un componente cache, che può riutilizzare le risposte precedenti per eliminare parzialmente o completamente alcune interazioni sulla rete

 

4. interfaccia uniforme

Per avere un caching efficiente in una rete, i componenti devono essere in grado di comunicare tramite un’interfaccia uniforme. Con un’interfaccia uniforme, il carico utile può essere trasferito in un formato standard.

4.1. Identificazione delle risorse

Una risorsa è un oggetto o la rappresentazione di qualcosa di significativo nel dominio applicativo. È possibile interagire con le risorse attraverso le API. Esempi di entità? Un Libro, un Ordine, un Post e qualsiasi altra entità che si può astrarre da un determinato contesto. Il concetto di risorsa è quindi molto simile a quello di oggetto nel mondo della programmazione ad oggetti.

4.2. Manipolazione delle risorse attraverso rappresentazioni

Una risorsa può essere rappresentata in molti modi diversi.
Ad esempio come HTML, XML, JSON o anche come file JPEG.
Questa regola significa che i clienti interagiscono con le risorse tramite le loro rappresentazioni, il che è un modo potente per mantenere i concetti di risorse astratti dalle loro interazioni. La rappresentazione più famosa utilizzata nelle implementazioni REST è il JSON . Un esempio di rappresentazione di una risorsa con JSON:

{
   "name": "Marco",
   "surname": "Rossi",
   "age" : 30

}

4.3  Hypermedia deve essere il motore dello stato dell’applicazione

Ciò significa solo che l’applicazione deve essere guidata da collegamenti, consentendo ai clienti di scoprire risorse tramite collegamenti ipertestuali. Come si può notare, molte di queste regole possono essere implementate nel protocollo HTTP. Pertanto, quando un’API utilizza correttamente HTTP, è un enorme passo avanti verso RESTful.

5. Sistema stratificato (LAYERED SYSTEM)

In un sistema a livelli, componenti intermedi come i proxy possono essere collocati tra client e server utilizzando l’interfaccia uniforme del web.
Uno dei vantaggi di un sistema a più livelli è che gli intermediari possono intercettare il traffico client-server per scopi specifici; ad esempio il caching o sicurezza.
Una soluzione basata su REST può essere composta da più livelli architettonici e quest’ultimi sono indipendenti l’uno dall’altro. I livelli possono essere aggiunti, rimossi, modificati o riordinati in risposta a come la soluzione deve evolversi.

6. Code On Demand

Questo vincolo facoltativo è inteso principalmente a consentire alla logica all’interno dei client (come i browser Web) di essere aggiornata indipendentemente dalla logica lato server. Al momento della tesi di Roy Fielding, il web era per lo più solo documenti statici e l’unico “client web” era il browser stesso. Oggi è normale che le app web basate su JavaScript stiano consumando API REST: le single page application rispettano in pieno questo punto.

e restFUL che significa?

Abbiamo appena descritto i principi di una architettura REST. Spesso però sentiamo parlare dell’acronimo RESTful nel contesto di REST. Sono sinonimi? No non significano esattemente la solita cosa: mentre REST viene definito con uno “stile architetturale” con delle caratteristiche e principi, RESTful viene in genere utilizzato per fare riferimento a servizi Web che implementano l’architettura REST. Un tipico esempio sono le API di sistemi che rispettano i vincoli e principi descritti nel paragrafo precedente.

VANTAGGI

Sono un estimatore dell’architettura RESTful; da quando adotto questo stile nei miei sistemi ho acquisito innumerevoli vantaggi, tra i quali:

Separazione tra client e server: il protocollo REST separa completamente l’interfaccia utente dal server. Questo ha alcuni vantaggi in fase di sviluppo:
  • Permette in grossi progetti di separare nel modo migliore il lavoro tra developer;
  • Consente l’evoluzione indipendente delle diverse componenti degli sviluppi: se ad es. oggi il frontend di una Web Application REST è scritto in Angular e tra due anni esce un fantastico nuovo framework per il frontend, è possibile sostituire il componente frontend senza modificare una riga di codice del backend (è fattibile anche il viceversa)
  • Portabilità dell’interfaccia ad altri tipi di piattaforme: l’interfaccia REST utilizzata da un frontend può essere riutilizzata a costo zero per sviluppare un applicazione Mobile. 

Visibilità, affidabilità e scalabilità: La separazione tra client e server ha un evidente vantaggio: il sistema può essere scalato senza troppi problemi. Client e Server possono risiedere su server differenti e come già spiegato è facilissimo scalare orizzontalmente un componente dell’architettura con pochissima difficoltà e con nessun impatto per l’altro componente.

Indipendenza da linguaggi e tecnologie specifiche : L’API REST è sempre indipendente dal tipo di piattaforma o linguaggio: l’API REST si adatta sempre al tipo di linguaggio o piattaforme utilizzate, il che conferisce notevole libertà nella scelta del linguaggio o framework per l’implementazione di un componente. Con un’API REST è possibile avere server PHP, Java, Python o Node.js o qualsiasi linguaggio di programmazione che vi viene in mente. L’unica cosa è che è indispensabile che le risposte alle richieste vengano sempre eseguite nella lingua utilizzata per lo scambio di informazioni, normalmente JSON.

conclusione

In questo articolo ho seguito un approccio differente dai migliaia di articoli che tentano di spiegare RestFul andando dritto all’implementazione nel framework figo del momento. È importante capire i principi di questa architettura per riuscire a sviluppare sistemi scalabili e affidabili. Ho tenuto a chiarire che l’implementazione REST che tutti noi conosciamo (vedi Api RestFul) è solo una possibile implementazione di questo stile architetturale. REST non ha solo cambiato il mondo del WEB; la potenza di questa architettura è molto utilizzata in contesti dove la scalabilità è un MUST. Per citarne uno, CoAP (Constrained Application Protocol) è un protocollo RESTful per dispositivi embedded (IOT) ed è stato progettato per utilizzare risorse minime sia sul dispositivo che sulla rete. 

La serie su REST prosegue nei seguenti articoli:

 

BIBLIOGRAFIA

Architectural Styles and the Design of Network-based Software Architectures(Roy T. Fielding)

 

A proposito di me

Dario Frongillo

Uno degli admin di Italiancoders e dell iniziativa devtalks.
Dario Frongillo è un software engineer e architect, specializzato in Web API, Middleware e Backend in ambito cloud native. Attualmente lavora presso NTT DATA, realtà di consulenza internazionale.
E' membro e contributor in diverse community italiane per developers; Nel 2017 fonda italiancoders.it, una community di blogger italiani che divulga articoli, video e contenuti per developers.

Gli articoli più letti

Articoli recenti

Commenti recenti