Challenge : Consommer un service Web

Durée : 2h.
Difficulté : ***

Ce challenge propose de faire des requêtes HTTPS GET, en Kotlin, avec Retrofit : la bibliothèque réseau la plus populaire pour Android.

À savoir, l'objectif est d'obtenir des informations sur les pays, à partir de l'API REST Countries, pour illustrer les requêtes HTTPS GET dans une application cliente mobile Android.
Remarque : la version 2.9 de Retrofit est utilisée (06.10.2021).

Voici les étapes d'implémentation :
> Configurer le projet Android Studio
> Analyser le résultat attendu
> Créer les modèles
> Créer l'interface d'API
> Faire une requête

> Configurer le projet Android Studio

L'objectif est de configurer le projet Android Studio pour utiliser les bibliothèques réseaux.

Tout d'abord, il s'agit d'ajouter la permission internet afin d'autoriser l'application à se connecter à internet.
De plus, les bibliothèques réseaux suivantes sont nécessaires au projet Android Studio :

  1. Créez un nouveau projet Android, appelons-le WonderfulWorld, avec Empty Activity comme modèle de projet.
  2. Ajoutez l'autorisation Internet, dans le fichier AndroidManifest.xml, entre les balises manifest et application :
  3. Dans le fichier Gradle Script, joint au module app/, incluez ces 3 bibliothèques :
    
    dependencies {
      implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
      implementation "com.squareup.retrofit2:converter-moshi:$moshi_version"
      implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
    }
    
    
  4. Dans le fichier Gradle Script joint à l'ensemble du projet, ajoutez les variables de version :
    
     ext.retrofit_version = '2.9.0'
     ext.moshi_version = '2.9.0'
     ext.okhttp_version = '4.9.0'
    
    

> Analyser le résultat attendu

Le but est de trouver, tester les requêtes HTTPS puis analyser le résultat avec Postman.

  1. Testez cette requête HTTPS avec Postman :
    
     https://restcountries.eu/rest/v2/all
    
    
  2. Ce qui suit est un extrait du résultat :
    
     [
       {
           "name": "Afghanistan",
           "topLevelDomain": [
               ".af"
           ],
           "alpha2Code": "AF",
           "alpha3Code": "AFG",
           "callingCodes": [
               "93"
           ],
           "capital": "Kabul",
           "altSpellings": [
               "AF",
               "Afġānistān"
           ],
           "region": "Asia",
           "subregion": "Southern Asia",
           "population": 27657145,
           "latlng": [
               33.0,
               65.0
           ],
           "demonym": "Afghan",
           "area": 652230.0,
           "gini": 27.8,
           "timezones": [
               "UTC+04:30"
           ],
           "borders": [
               "IRN",
               "PAK",
               "TKM",
               "UZB",
               "TJK",
               "CHN"
           ],
           "nativeName": "افغانستان",
           "numericCode": "004",
           "currencies": [
               {
                   "code": "AFN",
                   "name": "Afghan afghani",
                   "symbol": "؋"
               }
           ],
           "languages": [
               {
                   "iso639_1": "ps",
                   "iso639_2": "pus",
                   "name": "Pashto",
                   "nativeName": "پښتو"
               },
               {
                   "iso639_1": "uz",
                   "iso639_2": "uzb",
                   "name": "Uzbek",
                   "nativeName": "Oʻzbek"
               },
               {
                   "iso639_1": "tk",
                   "iso639_2": "tuk",
                   "name": "Turkmen",
                   "nativeName": "Türkmen"
               }
           ],
           "translations": {
               "de": "Afghanistan",
               "es": "Afganistán",
               "fr": "Afghanistan",
               "ja": "アフガニスタン",
               "it": "Afghanistan",
               "br": "Afeganistão",
               "pt": "Afeganistão",
               "nl": "Afghanistan",
               "hr": "Afganistan",
               "fa": "افغانستان"
           },
           "flag": "https://restcountries.eu/data/afg.svg",
           "regionalBlocs": [
               {
                   "acronym": "SAARC",
                   "name": "South Asian Association for RC",
                   "otherAcronyms": [],
                   "otherNames": []
               }
           ],
           "cioc": "AFG"
       },
       {
           "name": "Åland Islands",
           "topLevelDomain": [
               ".ax"
           ],
           "alpha2Code": "AX",
           "alpha3Code": "ALA",
           "callingCodes": [
               "358"
           ],
           "capital": "Mariehamn",
    
  3. Remarquez la liste des pays, indiquée par [], et l'objet pays, indiqué par {}.
Ensuite, il s'agit de créer les classes de données représentant un pays, depuis l'API REST Countries.

> Créer les modèles

Le but est de créer les classes de données Kotlin représentant les données distantes.
Par exemple, l'application WonderfulWord a besoin du :

La bibliothèque Moshi convertit la réponse JSON en objets (désérialisation de la réponse en POKO).
Premièrement, Pays a un nom, une capitale et une liste de langue.
Deuxièmement, la Langue a un nom.

  1. Créez la classe de données Pays :
    
     data class Country(val name: String,
     val capital: String, val languages: List)
    
    
  2. Créez la classe de données Language :
    
    data class Language(val name: String)
    
    
Remarque : le nom des attributs est important et doit être exactement comme dans la réponse JSON du serveur.

> Créer l'interface API

Le but est de créer l'interface représentant les requêtes.

  1. Créez l'interface CountriesService :
    
     interface CountriesService {
         @GET("/rest/v2/all")
         fun listCountries(): Call<List<Country>>
     }
    
    
Remarque : attention aux imports

import retrofit2.Call
import retrofit2.http.GET

> Faire une requête

L'objectif est de créer un client Retrofit pour faire une requête, obtenir des pays avec leurs langues.

  1. Ajoutez le point d'entré de l'API, en tant que variable statique dans MainActivity :
    
     companion object {
             const val URL_COUNTRY_API =
              "https://restcountries.eu/"
         }
    
    
  2. Instanciez un client Retrofit dans MainActivity :
    
     val retro = Retrofit.Builder()
            .baseUrl(URL_COUNTRY_API)
            .addConverterFactory(MoshiConverterFactory.create())
            .build()
    
    
  3. Créez la variable service :
    
     val service = retro.create(CountriesService::class.java)
    
    
  4. Créez la variable countryRequest :
    
    val countryRequest = service.listCountries()
    
    
  5. Envoyez la demande de manière asynchrone :
    
     countryRequest.enqueue(object : Callback<List<Country>> {
             override fun onResponse(call: Call<List<Country>>,
                                      response: Response<List<Country>>) {
                 val allCountry = response.body()
                 for (c in allCountry!!)
                     Log.v(
                         MainActivity::class.simpleName,
                         "NAME: ${c.name} \n
                         CAPITAL: ${c.capital} \n
                         Language: ${c.languages} "
                     )
             }
    
             override fun onFailure(call: Call<List<Country>>,
                                      t: Throwable) {
                 Log.i(MainActivity::class.simpleName, "on FAILURE!")
             }
    
         })
    
    

La réponse est dans la variable allCountry ; si non, vérifiez votre accès à internet depuis votre smartphone (ou votre ordinateur portable, si vous utilisez un émulateur).

</> Solution du challenge

Obtenez les codes sources dans les Ressources supplémentaires de ce thème sur la Communication HTTPS.