API REST
REST
Nel modello REST (Representational State Transfer) la risorsa è una struttura dati, descritta tramite un modello ed un formato. L’API mette a disposizione l’accesso a questa risorsa tramite una interfaccia standard di comandi, che resta identica qualsiasi sia il tipo di risorsa.
I principali comandi previsti sono:
- GET: effettua una query di ricerca di una o più istanze della risorsa
- POST: aggiunta di una nuova istanza
- DELETE: eliminazione di una istanza
- PATCH/PUT: modifica di una istanza esistente.
Vediamole singolarmente:
GET
Di norma sono previste due tipologie di URL:
/api/risorsa/api/risorsa/{id}
In entrambi i casi il metodo usato è GET. Nella prima URL si richiedono tutte le istanze di quella risorsa. Ad esempio se abbiamo una lista di utenti da scaricare, la GET non parametrica restituisce tutti gli utenti.
Se invece si vuole filtrare un sottoinsieme di risorse, il metodo base è quello della queryString:
/api/risorsa/?attributo1=valore1&attributo2=valore2&...
Questo meccanismo si può usare anche per paginare i risultati, quando sono troppi, introducendo un parametro speciale ad esempio page=1.
Nella situazione in cui invece si richiede un utente specifico, questo va identificato da un id univoco.
/api/risorsa/26
POST
La POST si usa per inserire un nuovo elemento nella lista di risorse.
Nel body viene quindi inserito l’elemento, ad esempio in formato JSON:
{
"title": "Studiare REST",
"DueDate": "1/1/2020",
"completed": false
}Di norma l’id non viene fornito, ma viene generato dal server, visto che il client non ha modo di identificare tutte le risorse disponibili
PUT
La PUT ha una struttura identica alla POST, ma concettualmente serve per modificare una risorsa esistente. Di norma quindi viene messo l’identificativo nella URL, in quanto già conosciuto dal client.
/api/risorsa/26
DELETE
La DELETE ha una URL simile a quella della GET, in quanto caso il comando è di cancellazione della risorsa.
/api/risorsa/31
Cancella la risorsa con id=31.
Sicurezza con JWT
Per gestire l’identità di accesso del client, ad inizio sessione il client invia tramite POST le proprie credenziali e riceve dal server un token di sessione, che lo identifica per tutta la durata della sessione. Il sistema REST è stateless, il controllo di sessione si limita a verificare se l’utente ha il permesso di accedere ai metodi sulla risorsa e può opzionalmente fare un log delle azioni svolte.
Il sistema di token più diffuso è il JSON Web Token (JWT), un sistema stateless di autenticazione che il server non ha bisogno di salvare nel proprio database. Il JWT è una stringa criptata nel seguente formato:
xxxxx.yyyyy.zzzzz
Dove;
xxxxx: è un header che identifica il tipo di token (algoritmo)
yyyyy: identifica l’utente e la scadenza del token ed altre eventuali informazioni
zzzzz: è la firma crittografica della sessione
Il token viene criptato dal server con una sua chiave privata segreta lato server ed inviato al client. Il client lo invia nell’header delle chiamate in questo modo:
"Authorization: Bearer xxxxx.yyyyy.zzzzz"
Il server decripta il token, identifica l’utente e grazie alla sua chiave privata verifica ruolo e permessi.
Conclusioni
Questi comandi corrispondono quindi alle operazioni CRUD (Create Read Update Delete) di un modello dati come un database.
Questa API utilizza direttamente i verbi della richiesta HTTP.
Rest quindi:
- definisce una interfaccia standard comune per qualsiasi tipologia di oggetto;
- questa interfaccia corrisponde dal punto di vista logico a operazioni CRUD;
- questa interfaccia corrisponde dal punto di vista della comunicazione a verbi http: in particolare i verbi e codici di risposta sono gli stessi dello standard http;
- le chiamate/risposte REST sono, come le chiamate http, senza stato, quindi sia i messaggi di richiesta che di risposta devono fornire tutto il contesto, senza presupporre sessioni attive.
Esempio di REST: TodoList
Realizzare una applicazione distribuita che gestisce una TODO list. Gli elementi della TODO list prevedono un titolo, una data di scadenza, e uno stato (completato/non completato). L’applicazione client mostrerà la lista delle TODO, permetterà di inserire una nuova TODO, permetterà di cancellare una TODO da quelle esistenti e permetterà di modificarne lo stato.
Per realizzare questo applicativo, progetteremo un Web Service con le seguenti fasi:
1) Progettazione del database.
2) Identificazione delle viste e dei servizi REST
3) Disegno dei tracciati JSON
4) Disegno dell’architettura dell’applicazione (quindi dei principali moduli dell’app distribuita).
Vediamo la realizzazione:
1) Database
In questo progetto è prevista una sola entità, quindi una sola tabella TODO.
| Nome campo | funzione |
id: int | id univoco |
title: varchar | titolo |
dueDate: date | data di scadenza |
completed: bool | stato di completamento |
Sono previste 4 query (oltre alla CREATE):
– INSERT into TODO (id, title, dueDate, completed) VALUES ($id, $title, $dueDate, $completed)
– SELECT id, title, dueDate, completed FROM TODO
– UPDATE TODO set completed=$completed WHERE id=$id
– DELETE TODO WHERE id=$id
2) Identificazione delle viste e dei servizi REST
I dati da mostrare corrispondono a quelli presenti nella tabella TODO.
I servizi REST saranno i seguenti:
| URL | Verbo | Azione |
{baseUrl}/todo | GET | Riceve tutte le TODO |
{baseUrl}/todo | POST | Aggiunge una TODO |
{baseUrl}/todo/$id | PUT | Modifica una todo con id=$id(per cambiarne lo stato) |
{baseUrl}/todo/$id | DELETE | Elimina una TODO con id=$id |
In questo caso non prevediamo la GET di una singola TODO.
3) Disegno dei tracciati JSON.
La struttura dati del JSON nella response di GET/POST/PUT è questa:
{
todos: [
{
id: $id,
title: $title,
date: $dueDate,
completed: $completed
},
...
]
}4) Disegno dell’architettura della web application:

