Appeler une API externe grâce à HttpClient en .NET

Quand on développe un projet personnel ou professionnel, on doit souvent utiliser des API tiers. Et bien souvent, on est confrontés à cette question : Comment nous connecter en toute sécurité aux API en .Net framework ou .Net Core à l’aide de C# ?

Pour moi, la réponse est simple : l’HTTP CLIENT

Mais attention ! bien faire est nécéssaire si vous ne voulez pas épuiser votre pool de connections et provoquer des problèmes à terme au sein de votre application.

Rapide rappel du HTPP :

L’Hypertext Tranfer Protocol (HTTP) est un protocole d’application pour les systèmes d’information distribués, collaboratifs et hypermédias. Il est le fondement de la communication de données pour le World Wide Web.

L’HtppClient, ce que nous allons utiliser, est une classe de base pour envoyer des requêtes HTTP et recevoir des réponses HTPP d’une ressource (ici une API) identifiée par un URI.

Ce que nous allons apprendre :

Nous allons interagir avec une API externe qui nous permettra de gérer des profils utilisateurs.

  • GET : récupérer une liste de commentaires , puis un unique commantaire via son ID.
  • PUT : créer un nouveau commentaire au sein de l’API
  • POST : mettre à jour les informations d’un utilisateur

Notre API Externe de test : Configuration rapide

Pour ce tutoriel, nous allons utiliser une API externe de test gratuite qui permet de faire des tests sur tous les types de requêtes : JsonPlaceholder.

Vous pouvez retrouver toute la documentation ici


Note : Cet exemple est fait en application console .NET CORE 3.1. Il n’a pas vocation a expliquer les bonnes pratiques des Task et de l’utilisation de l’asynchronisme.

Création de notre modèle de données

Avant toute chose, nous allons créer une créer un modèle de données qui correspond au modèle de l’API. Selon la documentation, les utilisateurs seront récupérées comme suit :

  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  }

Nous allons donc créer une classe C# nommée ReviewDto.cs qui nous permettra de manipuler les Json récupérés de l’API externe comme ceci :

    public class ReviewDto
    {
        [JsonPropertyName("userId")]
        public string UserId { get; set; }
        [JsonPropertyName("id")]
        public int Id { get; set; }
        [JsonPropertyName("title")]
        public string Title { get; set; }
        [JsonPropertyName("body")]
        public string Body { get; set; }
    }

Requête GET

Notre modèle étant prêt nous allons pouvoir faire notre première requête GET.

Récupération de tous les commentaires postés

private const string baseUrl = "https://jsonplaceholder.typicode.com";
       
      public static List<ReviewDto> GetAllReviews()
      {
         string url = $"{baseUrl}/posts";

         using (HttpClient client = new HttpClient())
         {
           client.BaseAddress = new Uri(url);
           client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

           HttpResponseMessage response = client.GetAsync(url).Result;

            if (!response.IsSuccessStatusCode)
              throw new Exception();

            string json = response.Content.ReadAsStringAsync().Result;

            List<ReviewDto> reviews = JsonConvert.DeserializeObject<List<ReviewDto>>(json);

            return reviews;
            }
        }

Ceci nous permet de récupérer une liste de 10 commentaires d’utilisateurs.

Ici donc voici ce que nous faisons :

  • nous construisons notre Url d’appel avec l’url de l’api externe (baseUrl) et le endpoint qui suivant la doc nous permet de récupérer tous les commentaires (/posts)
  • nous créons notre HTTP client dans un using en lui spécifiant notre URI ainsi que l’acceptation du Json pour le header.
  • Ensuite nous utilisons notre client qui dispose d’une méthode GetAsync (avec en paramètre notre url complete d’appel vers l’api externe). Et nous stockons la réponse dans une variable.
  • Nous récupérons notre json au sein du content de la réponse.
  • Nous déserialisons notre json précédemment récupéré en une liste d’objets ReviewDto pour pouvoir le manipuler.

Et voilà. A ce stade, nous récupérons une liste de 100 commentaires.

Récupération d’un utilisateur par son ID :

        public static ReviewDto GetReviewByUserId(int userId) // ici userId = 2
        {
            string url = $"{baseUrl}/posts/{userId}";

            using (HttpClient client = new HttpClient())
            {
                client.BaseAddress = new Uri(url);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = client.GetAsync(url).Result;

                if (!response.IsSuccessStatusCode)
                    throw new Exception();

                string content = response.Content.ReadAsStringAsync().Result;

                ReviewDto reviewById = JsonConvert.DeserializeObject<ReviewDto>(content);

                return reviewById;
            }
        }

Ici, même principe que pour récupérer toute une liste de commentaires, sauf que cette fois, nous passons en paramètre de notre endpoint d’appels au sein de l’url un userId. Ici, je passe l’ID 2 pour l’exemple, qui est un ID présent dans la liste de tous les commentaires récupérés.

De plus à la déserialisation, nous ne récupérons plus une liste d’objets ReviewDto, mais seulement l’objet puisque le but ici est de récupérer un unique commentaire.

Simpliste non ?

Requête POST ou PUT

Nous allons ici mettre à jour une donnée en ajouter un commentaire pour notre id = 2.

public static async void UpdateCommentAsync()
        {
            ReviewDto reviewToUpdate = GetReviewByUserId(2); // on recupère notre avis qui a l'id 2 

            reviewToUpdate.Body = "Super bien ce tutorial !!"; // on update notre objet avec un commentaire

            string json = JsonConvert.SerializeObject(reviewToUpdate); /// on transorme notre objet en json

            var client = new HttpClient();
            using (var request = new HttpRequestMessage(HttpMethod.Post, $"{baseUrl}/posts")) // HERE CHANGE POST TO PUT FOR A CREATION DOC
            {
                using var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
                request.Content = stringContent;

                using var send =  await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
                    .ConfigureAwait(false);

                if (!send.IsSuccessStatusCode)
                    throw new Exception();

                var response = send.EnsureSuccessStatusCode();
            }

            GetReviewByUserId(2);
        }

Ici que faisons nous :

  • Nous récupérons l’avis à modifier.
  • Nous le mettons à jour avec le commentaire que nous voulons (ici => « super bien ce tutorial)
  • Nous sérialisons notre objet, autrement dit, nous le transformons en json
  • Nous faisons notre méthode POST.

Vous devriez avoir en réponse : {StatusCode: 201, ReasonPhrase: 'Created', }