Utiliser un service web RESTful

L’intégration d’un service web dans une application est un scénario courant. Cet article montre comment utiliser un service web RESTful à partir d’une Xamarin.Forms application.

REST (Representational State Transfer) est un style d’architecture pour la création de services web. Les requêtes REST sont effectuées via HTTP en utilisant les mêmes verbes HTTP que ceux utilisés par les navigateurs web pour récupérer des pages web et envoyer des données aux serveurs. Les verbes sont :

  • GET : cette opération est utilisée pour récupérer des données auprès du service web.
  • POST : cette opération est utilisée pour créer un nouvel élément de données sur le service web.
  • PUT : cette opération est utilisée pour mettre à jour un élément de données sur le service web.
  • PATCH : cette opération est utilisée pour mettre à jour un élément de données sur le service web en décrivant un ensemble d’instructions sur la façon dont l’élément doit être modifié. Ce verbe n’est pas utilisé dans l’exemple d’application.
  • DELETE : cette opération est utilisée pour supprimer un élément de données sur le service web.

Les API de service web qui adhèrent à REST sont appelées API RESTful et elles sont définies en utilisant les éléments suivants :

  • URI de base.
  • Des méthodes HTTP, comme GET, POST, PUT, PATCH ou DELETE.
  • Type de média pour les données, tel que JavaScript Object Notation (JSON).

Les services web RESTful utilisent généralement des messages JSON pour retourner des données au client. JSON est un format d’échange de données textuel qui produit des charges utiles compactes, ce qui entraîne une réduction des exigences en bande passante lors de l’envoi de données. L’exemple d’application utilise la bibliothèque code source ouvert NewtonSoft JSON.NET pour sérialiser et désérialiser les messages.

La simplicité de REST a aidé à le rendre la méthode principale d’accès aux services web dans les applications mobiles.

Lorsque l’exemple d’application est exécuté, il se connecte à un service REST hébergé localement, comme illustré dans la capture d’écran suivante :

Exemple d’application

Remarque

Dans iOS 9 et versions ultérieures, App Transport Security (ATS) applique des connexions sécurisées entre les ressources Internet (comme le serveur principal de l’application) et l’application, ce qui empêche la divulgation accidentelle d’informations sensibles. Étant donné que ATS est activé par défaut dans les applications créées pour iOS 9, toutes les connexions sont soumises aux exigences de sécurité ATS. Si les connexions ne répondent pas à ces exigences, elles échouent avec une exception.

ATS peut être supprimé s’il n’est pas possible d’utiliser le protocole HTTPS et la communication sécurisée pour les ressources Internet. Pour ce faire, mettez à jour le fichier Info.plist de l’application. Pour plus d’informations, consultez App Transport Security.

Consommer le services web

Le service REST est écrit à l’aide de ASP.NET Core et fournit les opérations suivantes :

Opération Méthode HTTP URI relatif Paramètres
Obtenir une liste de tâches GET /api/todoitems/
Créer un élément de tâche POST /api/todoitems/ Un objet TodoItem au format JSON
Mettre à jour une tâche PUT /api/todoitems/ Un objet TodoItem au format JSON
Supprimer une tâche DELETE /api/todoitems/{id}

La majorité des URI incluent l’ID TodoItem dans le chemin d’accès. Par exemple, pour supprimer l’ID TodoItem dont l’ID est 6bb8a868-dba1-4f1a-93b7-24ebce87e243, le client envoie une demande DELETE à http://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243. Pour plus d’informations sur le modèle de données utilisé dans l’exemple d’application, consultez Modélisation des données.

Lorsque l’infrastructure d’API web reçoit une requête qu’elle achemine vers une action. Ces actions sont simplement des méthodes publiques dans la TodoItemsController classe. L’infrastructure utilise l’intergiciel de routage pour faire correspondre les URL des requêtes entrantes et les mapper aux actions. Les API REST doivent utiliser le routage d’attributs pour le modèle que la fonctionnalité de l’application est un ensemble de ressources dont les opérations sont représentées par des verbes HTTP. Le routage par attributs utilise un ensemble d’attributs pour mapper les actions directement aux modèles de routes. Pour plus d’informations sur le routage des attributs, consultez Routage des attributs pour les API REST. Pour plus d’informations sur la création du service REST à l’aide de ASP.NET Core, consultez Création de services principaux pour les applications mobiles natives.

La HttpClient classe est utilisée pour envoyer et recevoir des requêtes via HTTP. Il fournit des fonctionnalités permettant d’envoyer des requêtes HTTP et de recevoir des réponses HTTP à partir d’une ressource identifiée par l’URI. Chaque requête est envoyée en tant qu’opération asynchrone. Pour plus d’informations sur les opérations asynchrones, consultez Vue d’ensemble du support asynchrone.

La HttpResponseMessage classe représente un message de réponse HTTP reçu du service web une fois qu’une requête HTTP a été effectuée. Il contient des informations sur la réponse, notamment le code d’état, les en-têtes et le corps du message. La HttpContent classe représente le corps HTTP et les en-têtes de contenu, tels que Content-Type et Content-Encoding. Le contenu peut être lu à l’aide de l’une ReadAs des méthodes, telles que ReadAsStringAsync et ReadAsByteArrayAsync, en fonction du format des données.

Créer l’objet HTTPClient

L’instance HttpClient est déclarée au niveau de la classe afin que l’objet se trouve tant que l’application doit effectuer des requêtes HTTP, comme indiqué dans l’exemple de code suivant :

public class RestService : IRestService
{
  HttpClient client;
  ...

  public RestService ()
  {
    client = new HttpClient ();
    ...
  }
  ...
}

Récupérer des données

La HttpClient.GetAsync méthode est utilisée pour envoyer la requête GET au service web spécifié par l’URI, puis recevoir la réponse du service web, comme illustré dans l’exemple de code suivant :

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);
  }
  ...
}

Le service REST envoie un code d’état HTTP dans la HttpResponseMessage.IsSuccessStatusCode propriété pour indiquer si la requête HTTP a réussi ou échoué. Pour cette opération, le service REST envoie le code d’état HTTP 200 (OK) dans la réponse, ce qui indique que la demande a réussi et que les informations demandées se situent dans la réponse.

Si l’opération HTTP a réussi, le contenu de la réponse est lu pour l’affichage. La HttpResponseMessage.Content propriété représente le contenu de la réponse HTTP et la HttpContent.ReadAsStringAsync méthode écrit de manière asynchrone le contenu HTTP dans une chaîne. Ce contenu est ensuite désérialisé de JSON vers une List instance TodoItem .

Avertissement

L’utilisation de la ReadAsStringAsync méthode pour récupérer une réponse volumineuse peut avoir un impact négatif sur les performances. Dans de telles circonstances, la réponse doit être désérialisée directement pour éviter d’avoir à le mettre entièrement en mémoire tampon.

Créer un flux

La HttpClient.PostAsync méthode est utilisée pour envoyer la requête POST au service web spécifié par l’URI, puis pour recevoir la réponse du service web, comme indiqué dans l’exemple de code suivant :

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’instance TodoItem est sérialisée dans une charge utile JSON pour l’envoi au service web. Cette charge utile est ensuite incorporée dans le corps du contenu HTTP qui sera envoyé au service web avant l’envoi de la requête avec la PostAsync méthode.

Le service REST envoie un code d’état HTTP dans la HttpResponseMessage.IsSuccessStatusCode propriété pour indiquer si la requête HTTP a réussi ou échoué. Les réponses courantes pour cette opération sont les suivantes :

  • 201 (CREATED) : la demande a entraîné la création d’une nouvelle ressource avant l’envoi de la réponse.
  • 400 (DEMANDE INCORRECTE) : la demande n’est pas comprise par le serveur.
  • 409 (CONFLIT) : la demande n’a pas pu être effectuée en raison d’un conflit sur le serveur.

Mettre à jour des données

La HttpClient.PutAsync méthode est utilisée pour envoyer la requête PUT au service web spécifié par l’URI, puis recevoir la réponse du service web, comme illustré dans l’exemple de code suivant :

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  ...
  response = await client.PutAsync (uri, content);
  ...
}

L’opération de la PutAsync méthode est identique à la PostAsync méthode utilisée pour créer des données dans le service web. Toutefois, les réponses possibles envoyées à partir du service web diffèrent.

Le service REST envoie un code d’état HTTP dans la HttpResponseMessage.IsSuccessStatusCode propriété pour indiquer si la requête HTTP a réussi ou échoué. Les réponses courantes pour cette opération sont les suivantes :

  • 204 (NO CONTENT) : la demande a été traitée avec succès et la réponse est intentionnellement vide.
  • 400 (DEMANDE INCORRECTE) : la demande n’est pas comprise par le serveur.
  • 404 (INTROUVABLE) : la ressource demandée n’existe pas sur le serveur.

Supprimer des données

La HttpClient.DeleteAsync méthode est utilisée pour envoyer la requête DELETE au service web spécifié par l’URI, puis recevoir la réponse du service web, comme illustré dans l’exemple de code suivant :

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.");
  }
  ...
}

Le service REST envoie un code d’état HTTP dans la HttpResponseMessage.IsSuccessStatusCode propriété pour indiquer si la requête HTTP a réussi ou échoué. Les réponses courantes pour cette opération sont les suivantes :

  • 204 (NO CONTENT) : la demande a été traitée avec succès et la réponse est intentionnellement vide.
  • 400 (DEMANDE INCORRECTE) : la demande n’est pas comprise par le serveur.
  • 404 (INTROUVABLE) : la ressource demandée n’existe pas sur le serveur.

Développement local

Si vous développez votre service web REST localement avec une infrastructure telle que ASP.NET’API web Core, vous pouvez déboguer votre service web et votre application mobile en même temps. Dans ce scénario, vous devez activer le trafic HTTP en texte clair pour le simulateur iOS et l’émulateur Android. Pour plus d’informations sur la configuration de votre projet pour autoriser la communication, consultez Connecter aux services web locaux.