Utilizzare un servizio Web RESTful
L'integrazione di un servizio Web in un'applicazione è uno scenario comune. Questo articolo illustra come usare un servizio Web RESTful da un'applicazione Xamarin.Forms .
REST (Representational State Transfer) è uno stile di architettura per la creazione di servizi Web. Le richieste REST vengono effettuate tramite HTTP usando gli stessi verbi HTTP usati dai Web browser per recuperare pagine Web e inviare dati ai server. I verbi sono:
- GET - Questa operazione viene usata per recuperare dati dal servizio Web.
- POST - Questa operazione viene usata per creare un nuovo elemento di dati nel servizio Web.
- PUT - Questa operazione viene usata per aggiornare un elemento di dati nel servizio Web.
- PATCH - Questa operazione viene usata per aggiornare un elemento di dati nel servizio Web descrivendo un set di istruzioni sulla modalità di modifica dell'elemento. Questo verbo non viene usato nell'applicazione di esempio.
- DELETE - Questa operazione viene usata per eliminare un elemento di dati nel servizio Web.
Le API del servizio Web conformi a REST sono denominate API RESTful e vengono definite usando:
- URI di base.
- Metodi HTTP, ad esempio GET, POST, PUT, PATCH o DELETE.
- Tipo di supporto per i dati, ad esempio JavaScript Object Notation (JSON).
I servizi Web RESTful usano in genere messaggi JSON per restituire dati al client. JSON è un formato di interscambio dati basato su testo che produce payload compatta, che comporta una riduzione dei requisiti di larghezza di banda durante l'invio di dati. L'applicazione di esempio usa la libreria open source NewtonSoft JSON.NET per serializzare e deserializzare i messaggi.
La semplicità di REST ha contribuito a renderlo il metodo principale per l'accesso ai servizi Web nelle applicazioni per dispositivi mobili.
Quando viene eseguita l'applicazione di esempio, si connetterà a un servizio REST ospitato in locale, come illustrato nello screenshot seguente:
Nota
In iOS 9 e versioni successive, App Transport Security (ATS) applica connessioni sicure tra le risorse Internet (ad esempio il server back-end dell'app) e l'app, impedendo così la divulgazione accidentale di informazioni riservate. Poiché ATS è abilitato per impostazione predefinita nelle app compilate per iOS 9, tutte le connessioni saranno soggette ai requisiti di sicurezza di ATS. Se le connessioni non soddisfano questi requisiti, avranno esito negativo con un'eccezione.
ATS può essere rifiutato esplicitamente se non è possibile usare il protocollo HTTPS e proteggere la comunicazione per le risorse Internet. A tale scopo, aggiornare il file Info.plist dell'app. Per altre informazioni, vedere App Transport Security.
Utilizzare il servizio Web
Il servizio REST viene scritto usando ASP.NET Core e fornisce le operazioni seguenti:
Operazione | Metodo HTTP | URI relativo | Parametri |
---|---|---|---|
Ottenere un elenco di elementi attività | GET | /api/todoitems/ | |
Creare un nuovo elemento attività | POST | /api/todoitems/ | Oggetto TodoItem formattato IN FORMATO JSON |
Aggiornare un elemento attività | PUT | /api/todoitems/ | Oggetto TodoItem formattato IN FORMATO JSON |
Eliminare un elemento attività | DELETE | /api/todoitems/{id} |
La maggior parte degli URI include l'ID TodoItem
nel percorso. Ad esempio, per eliminare il TodoItem
cui ID è 6bb8a868-dba1-4f1a-93b7-24ebce87e243
, il client invia una richiesta DELETE a http://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243
. Per altre informazioni sul modello di dati usato nell'applicazione di esempio, vedere Modellazione dei dati.
Quando il framework API Web riceve una richiesta, instrada la richiesta a un'azione. Queste azioni sono semplicemente metodi pubblici nella TodoItemsController
classe . Il framework usa il middleware di routing per trovare le corrispondenze con gli URL delle richieste in ingresso ed eseguirne il mapping alle azioni. Le API REST devono usare il routing degli attributi per il modello di funzionalità dell'app come set di risorse le cui operazioni sono rappresentate dai verbi HTTP. Il routing con attributi usa un set di attributi per eseguire il mapping delle azioni direttamente ai modelli di route. Per altre informazioni sul routing degli attributi, vedere Routing degli attributi per le API REST. Per altre informazioni sulla creazione del servizio REST tramite ASP.NET Core, vedere Creazione di servizi back-end per applicazioni per dispositivi mobili native.
La HttpClient
classe viene usata per inviare e ricevere richieste tramite HTTP. Fornisce funzionalità per l'invio di richieste HTTP e la ricezione di risposte HTTP da una risorsa identificata da un URI. Ogni richiesta viene inviata come operazione asincrona. Per altre informazioni sulle operazioni asincrone, vedere Panoramica del supporto asincrono.
La HttpResponseMessage
classe rappresenta un messaggio di risposta HTTP ricevuto dal servizio Web dopo che è stata effettuata una richiesta HTTP. Contiene informazioni sulla risposta, inclusi il codice di stato, le intestazioni e qualsiasi corpo. La HttpContent
classe rappresenta il corpo HTTP e le intestazioni del contenuto, ad esempio Content-Type
e Content-Encoding
. Il contenuto può essere letto usando uno dei ReadAs
metodi, ad esempio ReadAsStringAsync
e ReadAsByteArrayAsync
, a seconda del formato dei dati.
Creare l'oggetto HTTPClient
L'istanza HttpClient
viene dichiarata a livello di classe in modo che l'oggetto si trovi finché l'applicazione deve effettuare richieste HTTP, come illustrato nell'esempio di codice seguente:
public class RestService : IRestService
{
HttpClient client;
...
public RestService ()
{
client = new HttpClient ();
...
}
...
}
Recupero dei dati
Il HttpClient.GetAsync
metodo viene usato per inviare la richiesta GET al servizio Web specificato dall'URI e quindi ricevere la risposta dal servizio Web, come illustrato nell'esempio di codice seguente:
public async Task<List<TodoItem>> RefreshDataAsync ()
{
...
Uri uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));
...
HttpResponseMessage response = await client.GetAsync (uri);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync ();
Items = JsonSerializer.Deserialize<List<TodoItem>>(content, serializerOptions);
}
...
}
Il servizio REST invia un codice di stato HTTP nella HttpResponseMessage.IsSuccessStatusCode
proprietà per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Per questa operazione il servizio REST invia il codice di stato HTTP 200 (OK) nella risposta, che indica che la richiesta è riuscita e che le informazioni richieste sono nella risposta.
Se l'operazione HTTP ha esito positivo, il contenuto della risposta viene letto per la visualizzazione. La HttpResponseMessage.Content
proprietà rappresenta il contenuto della risposta HTTP e il HttpContent.ReadAsStringAsync
metodo scrive in modo asincrono il contenuto HTTP in una stringa. Questo contenuto viene quindi deserializzato da JSON a un List
di TodoItem
istanze.
Avviso
L'uso del ReadAsStringAsync
metodo per recuperare una risposta di grandi dimensioni può avere un impatto negativo sulle prestazioni. In tali circostanze, la risposta deve essere deserializzata direttamente per evitare di dover memorizzarla completamente nel buffer.
Crea flusso
Il HttpClient.PostAsync
metodo viene usato per inviare la richiesta POST al servizio Web specificato dall'URI e quindi per ricevere la risposta dal servizio Web, come illustrato nell'esempio di codice seguente:
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
Uri uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));
...
string json = JsonSerializer.Serialize<TodoItem>(item, serializerOptions);
StringContent content = new StringContent (json, Encoding.UTF8, "application/json");
HttpResponseMessage response = null;
if (isNewItem)
{
response = await client.PostAsync (uri, content);
}
...
if (response.IsSuccessStatusCode)
{
Debug.WriteLine (@"\tTodoItem successfully saved.");
}
...
}
L'istanza TodoItem
viene serializzata in un payload JSON per l'invio al servizio Web. Questo payload viene quindi incorporato nel corpo del contenuto HTTP che verrà inviato al servizio Web prima che la richiesta venga effettuata con il PostAsync
metodo .
Il servizio REST invia un codice di stato HTTP nella HttpResponseMessage.IsSuccessStatusCode
proprietà per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Le risposte comuni per questa operazione sono:
- 201 (CREATED): la richiesta ha generato la creazione di una nuova risorsa prima dell'invio della risposta.
- 400 (RICHIESTA NON VALIDA): la richiesta non viene riconosciuta dal server.
- 409 (CONFLICT) - Impossibile eseguire la richiesta a causa di un conflitto nel server.
Aggiornamento dei dati
Il HttpClient.PutAsync
metodo viene usato per inviare la richiesta PUT al servizio Web specificato dall'URI e quindi ricevere la risposta dal servizio Web, come illustrato nell'esempio di codice seguente:
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
response = await client.PutAsync (uri, content);
...
}
L'operazione del PutAsync
metodo è identica al PostAsync
metodo usato per la creazione di dati nel servizio Web. Tuttavia, le possibili risposte inviate dal servizio Web differiscono.
Il servizio REST invia un codice di stato HTTP nella HttpResponseMessage.IsSuccessStatusCode
proprietà per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Le risposte comuni per questa operazione sono:
- 204 (NESSUN CONTENUTO): la richiesta è stata elaborata correttamente e la risposta è intenzionalmente vuota.
- 400 (RICHIESTA NON VALIDA): la richiesta non viene riconosciuta dal server.
- 404 (NON TROVATO): la risorsa richiesta non esiste nel server.
Eliminare dati
Il HttpClient.DeleteAsync
metodo viene usato per inviare la richiesta DELETE al servizio Web specificato dall'URI e quindi ricevere la risposta dal servizio Web, come illustrato nell'esempio di codice seguente:
public async Task DeleteTodoItemAsync (string id)
{
Uri uri = new Uri (string.Format (Constants.TodoItemsUrl, id));
...
HttpResponseMessage response = await client.DeleteAsync (uri);
if (response.IsSuccessStatusCode)
{
Debug.WriteLine (@"\tTodoItem successfully deleted.");
}
...
}
Il servizio REST invia un codice di stato HTTP nella HttpResponseMessage.IsSuccessStatusCode
proprietà per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Le risposte comuni per questa operazione sono:
- 204 (NESSUN CONTENUTO): la richiesta è stata elaborata correttamente e la risposta è intenzionalmente vuota.
- 400 (RICHIESTA NON VALIDA): la richiesta non viene riconosciuta dal server.
- 404 (NON TROVATO): la risorsa richiesta non esiste nel server.
Sviluppo locale
Se si sviluppa il servizio Web REST in locale con un framework come ASP.NET'API Web core, è possibile eseguire il debug del servizio Web e dell'app per dispositivi mobili contemporaneamente. In questo scenario è necessario abilitare il traffico HTTP non crittografato per il simulatore iOS e l'emulatore Android. Per informazioni sulla configurazione del progetto per consentire la comunicazione, vedere Connessione ai servizi Web locali.