Representational state transfer
# Representational state transfer

Representational state transfer (REST) è uno stile architetturale per sistemi distribuiti. L'espressione "representational state transfer" e il suo acronimo, REST, fu introdotto nel 2000 nella tesi di dottorato di Roy Fielding, uno dei principali autori delle specifiche dell'HyperText Transfer Protocol (HTTP), e vennero rapidamente adottati dalla comunità di sviluppatori Internet.

Il termine REST rappresenta un sistema di trasmissione di dati su HTTP senza ulteriori livelli, quali ad esempio SOAP. I sistemi REST non prevedono il concetto di sessione, ovvero sono stateless, come approfondito successivamente.

L'architettura REST si basa su HTTP. Il funzionamento prevede una struttura degli URL ben definita che identifica univocamente una risorsa o un insieme di risorse e l'utilizzo dei metodi HTTP specifici per il recupero di informazioni (GET), per la modifica (POST, PUT, PATCH, DELETE) e per altri scopi (OPTIONS, ecc.). Questo particolare aspetto è approfondito nella sezione "Relazione tra gli URL e i metodi HTTP".

## Principi

REST prevede che la scalabilità del Web e la crescita siano risultati di pochi principi chiave di progettazione:

* lo stato dell'applicazione e le funzionalità sono divisi in risorse web
* ogni risorsa è unica e indirizzabile usando sintassi universale per uso nei link ipertestuali
* tutte le risorse sono condivise come interfaccia uniforme per il trasferimento di stato tra client e risorse, questo consiste in:
   * un insieme vincolato di operazioni ben definite
   * un insieme vincolato di contenuti, opzionalmente supportato da codice a richiesta
   * un protocollo che è:
      * client-server
      * privo di stato (stateless)
      * memorizzabile in cache
      * a livelli.

Fielding descrive l'effetto dell'architettura REST sulla scalabilità in questo modo:

«REST’s client-server separation of concerns simplifies component implementation, reduces the complexity of connector semantics, improves the effectiveness of performance tuning, and increases the scalability of pure server components. Layered system constraints allow intermediaries — proxies, gateways, and firewalls — to be introduced at various points in the communication without changing the interfaces between components, thus allowing them to assist in communication translation or improve performance via large-scale, shared caching. REST enables intermediate processing by constraining messages to be self-descriptive: interaction is stateless between requests, standard methods and media types are used to indicate semantics and exchange information, and responses explicitly indicate cacheability.»

«La separazione REST client-server degli interessi semplifica l'implementazione del componente, riduce la complessità della semantica del connettore, migliora l'efficacia dell'ottimizzazione delle prestazioni ed aumenta la scalabilità di componenti server puri. I vincoli di sistema a strati permettono di introdurre intermediari — proxy, gateway, e firewall — in vari punti della comunicazione senza cambiare le interfacce tra i componenti, consentendo loro di assistere nella traduzione della comunicazione o migliorare le prestazioni tramite cache condivisa di larga scala. REST consente l'elaborazione intermedia vincolando i messaggi ad essere auto-descrittivi: l'interazione è priva di stato tra le richieste, i metodi di base ed i tipi di media sono utilizzati per indicare la semantica e scambiare informazioni e le risposte indicano esplicitamente la possibilità di memorizzare nella cache.»

(Fielding, 2000)

## Vincoli

L'approccio architetturale REST è definito dai seguenti sei vincoli applicati ad un'architettura, mentre lascia libera l'implementazione dei singoli componenti.

Client–server. Un insieme di interfacce uniformi separa i client dai server. Questa separazione di ruoli e compiti significa che, per esempio, il client non si deve preoccupare del salvataggio delle informazioni, che rimangono all'interno dei singoli server. In questo modo la portabilità del codice del client ne trae vantaggio. I server non si devono fare carico dell'interfaccia grafica o dello stato dell'utente, in questo modo l'hardware può essere più semplice e maggiormente scalabile. Server e client possono essere sostituiti e sviluppati indipendentemente fintanto che l'interfaccia non viene modificata.

Stateless. La comunicazione client–server è vincolata in modo che nessun contesto client venga memorizzato sul server tra le richieste. Ciascuna richiesta dai vari client contiene tutte le informazioni necessarie per richiedere il servizio e lo stato della sessione è contenuto nel client. Lo stato della sessione può anche essere trasferito al server attraverso un altro servizio di memorizzazione persistente, per esempio un database.

Cacheable. Come nel World Wide Web, i client possono mettere in cache le risposte. Queste devono in ogni modo definirsi implicitamente o esplicitamente cacheable o no, in modo da prevenire che i client possano riutilizzare stati vecchi e dati errati. Una corretta gestione della cache può ridurre o parzialmente eliminare le comunicazioni client-server migliorando scalabilità e prestazioni.

Layered system. La struttura del sistema "a strati" (letteralmente dall'inglese) rende possibile per esempio pubblicare le API in un server, memorizzare i dati in un secondo server e gestire l'autenticazione delle richieste in un terzo server. Questo comporta che un client non può sapere se è connesso direttamente a un server finale oppure a uno della catena.

Code on demand. (opzionale) I server possono temporaneamente estendere o personalizzare le funzionalità del client trasferendo del codice eseguibile. Per esempio questo può includere componenti compilati come Applet Java o linguaggi di scripting lato client come per esempio JavaScript. Il concetto di Code on demand è l'unico vincolo opzionale per la definizione di un'architettura REST.

Uniform interface. Un'interfaccia di comunicazione omogenea tra client e server permette di semplificare e disaccoppiare l'architettura, per poterla modificare separatamente a blocchi.

## Il principio fondamentale di REST: le risorse

Un concetto importante in REST è l'esistenza di risorse (fonti di informazioni), a cui si può accedere tramite un identificatore globale (un URI).

Per utilizzare le risorse, le componenti di una rete (componenti client e server) comunicano attraverso un'interfaccia standard (per esempio HTTP) per scambiare rappresentazioni di queste risorse, ovvero il documento che trasmette le informazioni. Per esempio, una risorsa cerchio potrebbe accettare e restituire una rappresentazione che specifica un punto per il centro e il raggio in formato SVG, ma potrebbe anche accettare e restituire una rappresentazione che specifica tre punti distinti qualsiasi lungo la circonferenza nel formato CSV.

Un numero qualsiasi di connettori (client, server, cache, tunnel ecc.) può mediare la richiesta, ma ogni connettore interviene senza conoscere la “storia passata” delle altre richieste; proprio per questo motivo l'architettura REST si definisce stateless, in opposizione ad altre architetture o protocolli stateful. Di conseguenza un'applicazione può interagire con una risorsa conoscendo due cose: l'identificatore della risorsa e l'azione richiesta. Non serve sapere se ci sono proxy, gateway, firewall, tunnel o altri meccanismi intermedi tra essa e il server in cui è presente l'informazione necessaria.

L'applicazione comunque deve conoscere il formato dell'informazione restituita, ovvero la sua rappresentazione. Tipicamente è un documento HTML, XML o JSON, ma possono essere anche immagini o altri contenuti.

## La relazione tra gli URL e i metodi HTTP

La tabella seguente mostra come i metodi HTTP sono tipicamente usati in una API RESTful:

Metodi HTTP :

| Uniform Resource Locator (URL) | GET | PUT | POST | DELETE |
| - | - | - | - | - |
| Collection (collezione), ad esempio http://api.example.com/resources/ | Restituisce un elenco di risorse e probabilmente altri dettagli sugli elementi che appartengono alla collezione. | Sostituisce l'intera collezione con un'altra collezione. | Crea un nuovo elemento nella collezione. Il codice di stato solitamente restituito è il 201 (Created). L'URI della nuova risorsa viene assegnato automaticamente ed è usualmente restituito da questa operazione (header Location). | Elimina l'intera collezione. |
| Element (elemento), ad esempio http://api.example.com/resources/item17 | Recupera una rappresentazione dell'elemento indirizzato nella collezione (identificato da item17), in un formato di dato (media type) appropriato. | Sostituisce l'elemento indirizzato nella collezione, o se non esiste, lo crea. | Tratta l'elemento della collezione secondo i propri diritti e crea un nuovo elemento all'interno. Generalmente non usato se usato il metodo PUT. | Elimina l'elemento identificato nella collezione. |

Il metodo GET è un metodo sicuro, ovvero un safe method o nullipotente, il che significa che la sua invocazione non produce alcun effetto collaterale: recuperare o accedere un record non lo modifica.

I metodi PUT e DELETE sono idempotenti, ossia lo stato del sistema rimane invariato indipendentemente dal numero di volte che la stessa richiesta viene ripetuta.

A differenza dei web services basati su SOAP, non esiste alcuno standard ufficiale per le API web RESTful. Questo perché REST è un insieme di linee guida per un'architettura, mentre SOAP è un protocollo.

REST non è uno standard di per sé, ma le implementazioni RESTful utilizzano degli standard, come ad esempio HTTP, URI, JSON e XML.

Molti sviluppatori inoltre descrivono le proprie API come RESTful, anche se queste API non soddisfano tutti i vincoli architetturali descritti sopra (in particolare l'interfaccia uniforme).

