Programming Notes
Think it, Code it, Run it    moschini.cloud  

Introduzione ai servizi REST
Data pubblicazione: 22 aprile 2023

Cos'è REST

REST, acronimo di REpresentational State Transfer, è un' architettura consolidata per la creazione di Web API. I servizi REST possono sfruttare il protocollo HTTP (ma anche altri protocolli come SMTP, SNMP) per lo scambio di dati. Le linee guida dell'architettura REST indicano di usare uno specifico metodo HTTP per un particolare tipo di chiamata.

L'insieme dei metodi HTTP (chiamati anche verbi), come GET, POST, PUT e DELETE, semplifica la corrispondenza tra le azioni CRUD (Create, Read, Update, Delete) e le chiamate HTTP che andremo ad effettuare:

Metodo HTTPOperazione CRUDDescrizione
POSTCreateCrea una nuova risorsa
GETReadOttiene una risorsa esistente
PUTUpdateAggiorna (sostituisce) una risorsa o ne modifica lo stato
DELETEDeleteElimina una risorsa
PATCHUpdate (parziale)Aggiorna parzialmente la risorsa
OPTIONSRitorna informazioni circa una determinata risorsa (metodi permessi per una risorsa)

Le chiamate ai sertivi REST avvengono specificando il metodo HTTP, l'URL, la risorsa ed eventuali informazioni legati al tipo di richiesta. Ad esempio, per invocare il servizio di lettura di un dato potremmo avanzare una richiesta di tipo GET all'indirizzo:

https://www.nomedelserver.cloud/api/articoli/3

In questo esempio, l'URL è dato da https://www.nomedelserver.cloud, mentre api è la directory che espone i servizi REST all'interno del server. La risorsa a cui vogliamo accedere in lettura è articoli (potrebbero essere gli articoli disponibili in un magazzino), infine 3 rappresenza la chiave, ovvero l'identificativo, dell'articolo che vogliamo leggere.

Se la chiamata va a buon fine, il servizio riponderà inviando al client i dati relativi alla risorsa. Il formato della risposta può essere JSON, XML, HTML, testuale.


Codici di risposta

Dopo aver invocato un servizio REST, per capire se la nostra richiesta è andata a buon fine oppure no, dobbiamo verificare lo stato (status) inviato dal server. E' un codice numerico di 3 cifre, in cui la prima cifra definisce la tipologia dello stesso:

  • 1xx: codici di informazione

Esempio:

  • il codice 100 Continue notifica al client che è stata ricevuta la parte iniziale della richiesta e questa non è stata rifiutata dal server; il client dovrebbe inviare la parte restante della richiesta oppure ignorare il codice se ha già provveduto ad inviare il resto.
  • 2xx: codici di successo

Esempio:

  • il codice 200 OK indica che la richiesta è andata a buon fine;
  • il codice 201 OK indica che la richiesta è andata a buon fine e la risorsa è stata creata (questo codice viene restituito, ad esempio, con una richiesta di tipo POST);
  • il codice 202 Accepted indica che la richiesta è stata ricevuta ma non ancora completata. Viene in genere utilizzato nelle richieste di esecuzione di elaborazioni batch.
  • 3xx: codici di reindirizzamento

Esempio:

  • il codice 301 Moved Permanently indica che l'URL della risorsa richiesta è stato modificato in modo permanente. Il nuovo URL è indicato nel campo Location dell'header.
  • 4xx: codici di errori del client

Esempio:

  • il codice 400 Bad Request indica che la richiesta non può essere recepita dal server a causa di una sintassi errata. Il client non dovrebbe ripetere la richiesta senza prima modificarla;
  • il codice 401 Unauthorized indica che la richiesta richiede l'autenticazione dell'utente. Il client può ripetere la stessa richiesta dopo aver valorizzato il campo Authorization in modo adeguato;
  • il codice 404 Not Found indica che il server non trova la risorsa richiesta, ad esempio, tramite GET;
  • il codice 409 Conflict indica che il server non può completare la richiesta a causa di un conflitto con lo stato corrente della risorsa.
  • 5xx: codici di errori del server

Esempio:

  • il codice 500 Internal Server Error indica che il server ha rilevato una condizione imprevista che gli ha impedito di soddisfare la richiesta;
  • il codice 501 Not Implemented indica che il metodo HTTP non è supportato dal server e, quidni, non può essere gestito;
  • il codice 503 Service Unavailable indica che il server non è pronto a gestire la richiesta.

Esempi con Postman

Vediamo alcuni esempi di servizi REST che è possibile invocare senza alcun metodo di autenticazione. Utilizzeremo il servizio open-source https://randomuser.me, tramite il quale è possibile generare dati utente casuali. Per testare questo servizio utilizzeremo Postman, uno strumento che permette, tra l'altro, di invocare API REST.

Postman può essere scaricato da questo indirizzo.

Dopo averlo installato e avviato, è sufficiente inserire una nuova request con metodo GET e inserire l'URL https://randomuser.me/api/:

Postman

Per eseguire la richiesta al servizio REST è sufficiente cliccare su Send. Nel pannelo inferiore, è possibile verificare il buon esito della richiesta verificando che lo status sia 200 OK. In questo caso, nel pannello Body viene visualizzato l'output della richiesta, ovvero i dati random di un utente:

{
    "results": [
        {
            "gender": "male",
            "name": {
                "title": "Mr",
                "first": "Alberto",
                "last": "Rodríguez"
            },
            "location": {
                "street": {
                    "number": 3194,
                    "name": "Calle de Toledo"
                },
                "city": "Pamplona",
                "state": "Ceuta",
                "country": "Spain",
                "postcode": 23083,
                "coordinates": {
                    "latitude": "-30.5412",
                    "longitude": "-177.6515"
                },
                "timezone": {
                    "offset": "-5:00",
                    "description": "Eastern Time (US & Canada), Bogota, Lima"
                }
            },
            "email": "alberto.rodriguez@example.com",
            "login": {
                "uuid": "0c35aa62-8afd-4d1d-b1b4-df22d069ea95",
                "username": "sadfrog876",
                "password": "admin",
                "salt": "GN811hZC",
                "md5": "f532b619eb627e5f1a58d642d7ce99bd",
                "sha1": "f9b6003152bfaab013c513edc0f308b860395afe",
                "sha256": "b0e25177d2cab23481bac1f1c40f791bbaf41508e6049ad34d8b7a594a6ef19c"
            },
            "dob": {
                "date": "1999-10-08T20:25:03.278Z",
                "age": 23
            },
            "registered": {
                "date": "2005-03-17T17:01:10.647Z",
                "age": 17
            },
            "phone": "980-469-663",
            "cell": "612-768-683",
            "id": {
                "name": "DNI",
                "value": "68093680-B"
            },
            "picture": {
                "large": "https://randomuser.me/api/portraits/men/18.jpg",
                "medium": "https://randomuser.me/api/portraits/med/men/18.jpg",
                "thumbnail": "https://randomuser.me/api/portraits/thumb/men/18.jpg"
            },
            "nat": "ES"
        }
    ],
    "info": {
        "seed": "d5d601bdff24dc24",
        "results": 1,
        "page": 1,
        "version": "1.4"
    }
}

E' possibile generare i dati di più utenti con una sola chiamata al servizio.

Per fare questo, è sufficiente modificare l'URL in: https://randomuser.me/api/?results=3 per generare i dati di tre utenti.

Si può anche decidere quali informazioni generare per il singolo utente. Ad esempio, per avere solo i dati relativi al nome, indirizzo email e numero di telefono si può utilizzare questa API: https://randomuser.me/api/?inc=name,email,phone.

Il risultato è:

{
    "results": [
        {
            "name": {
                "title": "Mr",
                "first": "Josif",
                "last": "Stojaković"
            },
            "email": "josif.stojakovic@example.com",
            "phone": "016-8403-080"
        }
    ],
    "info": {
        "seed": "883a251f1eccb431",
        "results": 1,
        "page": 1,
        "version": "1.4"
    }
}

Naturalmente è possibile combinare più parametri nella chiamata al servizio, separandoli con il carattere &:

https://randomuser.me/api/?results=3&inc=name,email,phone

La risposta del servizio sarà:

{
    "results": [
        {
            "name": {
                "title": "Ms",
                "first": "Clara",
                "last": "Guerrero"
            },
            "email": "clara.guerrero@example.com",
            "phone": "(665) 211 8714"
        },
        {
            "name": {
                "title": "Ms",
                "first": "Eusébia",
                "last": "Pinto"
            },
            "email": "eusebia.pinto@example.com",
            "phone": "(53) 5129-4386"
        },
        {
            "name": {
                "title": "Mrs",
                "first": "Radmila",
                "last": "Gayduk"
            },
            "email": "radmila.gayduk@example.com",
            "phone": "(097) Q62-4573"
        }
    ],
    "info": {
        "seed": "734e7ed69948dbdd",
        "results": 3,
        "page": 1,
        "version": "1.4"
    }
}

Nel prossimo articolo, vedremo come creare un insieme di API con cui gestire le operazioni CRUD su una risorsa.