Utilizzare un servizio Web basato su REST
REST (Representational State Transfer) è uno stile di architettura per la creazione di servizi Web. Le richieste REST vengono in genere effettuate tramite HTTPS usando gli stessi verbi HTTP usati dai Web browser per recuperare le 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.
- DELETE - Questa operazione viene usata per eliminare un elemento di dati nel servizio Web.
Le API del servizio Web conformi a REST vengono definite tramite:
- 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 basati su REST usano in genere messaggi JSON per restituire i 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. La semplicità di REST ha contribuito a renderlo il metodo principale per l'accesso ai servizi Web nelle app per dispositivi mobili.
Nota
L'accesso a un servizio Web richiede spesso la programmazione asincrona. Per altre informazioni sulla programmazione asincrona, vedere Programmazione asincrona con async e await.
Operazioni del servizio Web
Il servizio REST di esempio viene scritto usando ASP.NET Core e fornisce le operazioni seguenti:
Operazione | Metodo HTTP | URI relativo | Parametri |
---|---|---|---|
Ottenere un elenco di elementi todo | GET | /api/todoitems/ | |
Creare un nuovo elemento todo | POST | /api/todoitems/ | Oggetto TodoItem formattato IN FORMATO JSON |
Aggiornare un elemento todo | PUT | /api/todoitems/ | Oggetto TodoItem formattato IN FORMATO JSON |
Eliminare un elemento todo | DELETE | /api/todoitems/{id} |
L'app MAUI .NET e il servizio Web usano la TodoItem
classe per modellare i dati visualizzati e inviati al servizio Web per l'archiviazione:
public class TodoItem
{
public string ID { get; set; }
public string Name { get; set; }
public string Notes { get; set; }
public bool Done { get; set; }
}
La ID
proprietà viene utilizzata per identificare in modo univoco ogni TodoItem
oggetto e viene utilizzata dal servizio Web per identificare i dati da aggiornare o eliminare. Ad esempio, per eliminare il TodoItem
cui ID è 6bb8a868-dba1-4f1a-93b7-24ebce87e243
, l'app MAUI .NET invia una richiesta DELETE a https://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243
.
Quando il framework API Web riceve una richiesta, instrada la richiesta a un'azione. Queste azioni sono metodi pubblici nella TodoItemsController
classe . Il framework API Web 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 modellare la funzionalità dell'app come set di risorse le cui operazioni sono rappresentate da 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 con ASP.NET Core, vedere Creazione di servizi back-end per applicazioni per dispositivi mobili native.
Creare l'oggetto HTTPClient
Un'app .NET multipiattaforma dell'interfaccia utente dell'app (.NET MAUI) può usare un servizio Web basato su REST inviando richieste al servizio Web con la HttpClient
classe . Questa classe 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.
L'oggetto HttpClient
deve essere dichiarato a livello di classe in modo che si trovi per tutto il tempo necessario per l'app per effettuare richieste HTTP:
public class RestService
{
HttpClient _client;
JsonSerializerOptions _serializerOptions;
public List<TodoItem> Items { get; private set; }
public RestService()
{
_client = new HttpClient();
_serializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
}
...
}
L'oggetto JsonSerializerOptions
viene usato per configurare la formattazione del payload JSON ricevuto e inviato al servizio Web. Per altre informazioni, vedere Come creare un'istanza di istanze di JsonSerializerOptions con System.Text.Json.
Recupero dei dati
Il HttpClient.GetAsync
metodo viene usato per inviare una richiesta GET al servizio Web specificato dall'URI e quindi ricevere la risposta dal servizio Web:
public async Task<List<TodoItem>> RefreshDataAsync()
{
Items = new List<TodoItem>();
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
try
{
HttpResponseMessage response = await _client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Items = JsonSerializer.Deserialize<List<TodoItem>>(content, _serializerOptions);
}
}
catch (Exception ex)
{
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
return Items;
}
I dati sono ricevuti dal servizio Web come HttpResponseMessage
oggetto . Contiene informazioni sulla risposta, inclusi il codice di stato, le intestazioni e qualsiasi corpo. Il servizio REST invia un codice di stato HTTP nella risposta, che può essere ottenuto dalla 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. La HttpResponseMessage.Content
proprietà rappresenta il contenuto della risposta e è di tipo HttpContent
. La HttpContent
classe rappresenta il corpo HTTP e le intestazioni del contenuto, ad esempio Content-Type
e Content-Encoding
. Il contenuto viene quindi letto in un string
oggetto usando il HttpContent.ReadAsStringAsync
metodo . viene string
quindi deserializzato da JSON a un List
di TodoItem
oggetti .
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 una richiesta POST al servizio Web specificato dall'URI e quindi per ricevere la risposta dal servizio Web:
public async Task SaveTodoItemAsync(TodoItem item, bool isNewItem = false)
{
Uri uri = new Uri(string.Format(Constants.RestUrl, string.Empty));
try
{
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);
else
response = await _client.PutAsync(uri, content);
if (response.IsSuccessStatusCode)
Debug.WriteLine(@"\tTodoItem successfully saved.");
}
catch (Exception ex)
{
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
}
In questo esempio 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 risposta, che può essere ottenuto dalla HttpResponseMessage.IsSuccessStatusCode
proprietà , per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Le risposte tipiche 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 una richiesta PUT al servizio Web specificato dall'URI e quindi ricevere la risposta dal servizio Web:
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 risposta, che può essere ottenuto dalla HttpResponseMessage.IsSuccessStatusCode
proprietà , per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Le risposte tipiche 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 una richiesta DELETE al servizio Web specificato dall'URI e quindi ricevere la risposta dal servizio Web:
public async Task DeleteTodoItemAsync(string id)
{
Uri uri = new Uri(string.Format(Constants.RestUrl, id));
try
{
HttpResponseMessage response = await _client.DeleteAsync(uri);
if (response.IsSuccessStatusCode)
Debug.WriteLine(@"\tTodoItem successfully deleted.");
}
catch (Exception ex)
{
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
}
Il servizio REST invia un codice di stato HTTP nella risposta, che può essere ottenuto dalla HttpResponseMessage.IsSuccessStatusCode
proprietà , per indicare se la richiesta HTTP ha avuto esito positivo o negativo. Le risposte tipiche 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 un servizio Web REST in locale con un framework come ASP.NET'API Web Core, è possibile eseguire il debug del servizio Web e dell'app MAUI .NET contemporaneamente. In questo scenario, per usare il servizio Web tramite HTTP da emulatori Android e simulatori iOS, è necessario abilitare il traffico HTTP non crittografato nell'app MAUI .NET. Per altre informazioni, vedere Connessione ai servizi Web locali da emulatori Android e simulatori iOS.