Comment implémenter Retrofit dans un projet Android via Kotlin ?

Implémentation de Retrofit dans un projet Android avec Coroutine
Clément BROSSETTEMis à jour le 25 Janv 2021
déploiement mobile android retroft kotlin

Retrofit, c’est quoi ?

La plupart des applications mobiles consomment des API REST JSON pour récupérer toutes les données nécessaires à leur fonctionnement.

Retrofit est aujourd’hui une des façons les plus simples d’implémenter des appels à des webservices REST.

Il s’agit d’un client REST développé par Jake Wharton ainsi que l’ensemble du staff de Square. Cette librairie est basée elle-même sur le client RESTREST (REpresentational State Transfer) est un style d'architecture logicielle qui fonctionne sous un certain nombre de contraintes. OKHttp (développée encore par Square !) et permet d’implémenter plus facilement et rapidement des requêtes réseau sur Android (Java ou Kotlin).

Retrofit nous évite ainsi d’installer manuellement toutes les parties nécessaires à l’exécution d’une requête, comme par exemple la gestion des réponses JSON ou la création d’une AsyncTask.

Cela permet un gain de temps conséquent et un code plus clair pour des performances équivalentes.

Depuis, Retrofit 2.6 supporte l’utilisation des coroutines. Cela permet de ne plus utiliser de callback ou la fonction enqueue.

Comment implémenter Retrofit dans un projet Android via Kotlin ?

Pour cet exemple, nous utiliserons https://jsonplaceholder.typicode.com/, qui est une APIUne API est un programme permettant à deux applications distinctes de communiquer entre elles et d’échanger des données. gratuite fournissant des données de test.

Ajout des permissions dans AndroidManifest.xml

La permission « INTERNET » est requise pour appeler des APIs dans une application AndroidAndroid est un système d'exploitation mobile basé sur Linux..

« ACCES_NETWORK_STATE » permet d'identifier l'état de la connexion internet de l'appareil.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
<uses-permission android:name="android.permission.INTERNET"/>

Implémentation des bibliothèques nécessaires

Pour installer Retrofit, il faut au minimum Java 8 + ou Android API 21 +.

Vous aurez ensuite besoin d’installer les dépendances suivantes en les renseignant dans le fichier build.gradle sous « dependencies ».

//Retrofit 
implementation ’com.squareup.retrofit2:retrofit:2.9.0’ 
implementation ’com.squareup.retrofit2:converter-gson:2.9.0//Coroutine 
implementation ’org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5’ 
implementation ’org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5

ApiClient Object : création d’une instance de Retrofit

Le client Retrofit doit être configuré avec une URLUniform Ressource Locator serveur (BASE_URL) ainsi qu’un convertisseur de requêtes. Ce convertisseur va permettre de convertir automatiquement la réponse JSON en objets. Ici, nous utilisons le convertisseur Gson. Il ne faut pas oublier le mot clé lazy, afin de ne pas dupliquer des instances de Retrofit.

package com.example.myapplication  
  
import com.google.gson.Gson  
import com.google.gson.GsonBuilder  
import okhttp3.OkHttpClient  
import retrofit2.Retrofit  
import retrofit2.converter.gson.GsonConverterFactory  
  
object ApiClient {  
    private const val BASE_URL: String = "https://jsonplaceholder.typicode.com/"  
  
    private val gson : Gson by lazy {  
      GsonBuilder().setLenient().create()  
    }  
  
    private val httpClient : OkHttpClient by lazy {  
      OkHttpClient.Builder().build()  
    }  
  
    private val retrofit : Retrofit by lazy {  
          Retrofit.Builder()  
            .baseUrl(BASE_URL)  
            .client(httpClient)  
            .addConverterFactory(GsonConverterFactory.create(gson))  
            .build()  
    }  
  
    val apiService :  ApiService by lazy{  
      retrofit.create(ApiService::class.java)  
    }  
}

ApiService class : création d’une interface qui regroupe les différents endpoints

On retrouve, sous forme d’annotations, la méthode et la route. Il faudra aussi spécifier le type de réponse afin que Gson puisse la désérialiser.

On remarquera la nécessité de préciser le type de paramètre avec les annotations @Path, @Query et @Body

package com.example.myapplication  
  
import com.example.myapplication.models.Comment  
import com.example.myapplication.models.Post  
import com.example.myapplication.models.User  
import retrofit2.Response  
import retrofit2.http.*  
  
interface ApiService {  
  
    @GET("users")  
    suspend fun getUsers(): Response<MutableList<User>>  
  
    @GET("posts/{num}")  
    suspend fun getPostById(@Path("num") num : Int): Response<Post>  
  
    @GET("comments")  
    suspend fun getCommentsByPost(@Query("postId") postId : Int): Response<MutableList<Comment>>  
  
    @POST("posts")  
    suspend fun createPost(@Body post: Post): Response<Post>  
}

Les méthodes suivantes sont disponibles :

  • @GET
  • @POST
  • @PUT
  • @DELETE
  • @PATCH

L’annotation @HEADER est aussi disponible ici pour définir un ou plusieurs headers sur un endpoint.

Les modèles

Ici, nous créons les modèles via des data classes afin de désérialiser les réponses et de stocker nos données. Point important, chaque champ de chaque modèle doit être identique à la réponse (nom et type) afin que la désérialisation de cette dernière fonctionne.

package com.example.myapplication.models

data class User(
val id: Int? = null,
 val name: String? = null,
 val userName: String? = null,
 val email: String? = null,
 val address : Address? = null,
 val phone: String? = null,
 val website: String? = null
)
package com.example.myapplication.models

data class Address(
val street: String? = null,
 val suite: String? = null,
 val city: String? = null,
 val zipCode: String? = null
)
package com.example.myapplication.models

data class Comment (
val postId: Int = 0,
 val id: Int = 0,
 val name: String? = null,
 val email: String? = null,
 val body: String? = null
)
package com.example.myapplication.models

data class Post (
val userId: Int = 0,
 val id: Int? = null,
 val title: String? = null,
 val body: String? = null
)

Un cas d’usage dans mainActivity

Pour cette partie, nous utiliserons Coroutine. Coroutine est un utilitaire de KotlinLangage de programmation permettant de développement des applications mobiles Android natives. permettant d’effectuer des tâches asynchrones. Pour cela, nous devons implémenter CoroutineScope qui indiquera où la coroutine devra envoyer les données. Ici, pour cet exemple, ce sera dans MainScope si l’on veut modifier l’affichage de la mainActivity.

Commençons par créer une nouvelle coroutine avec la fonction launch et la restreindre au main thread avec Dispachers.Main.

Le try/catch est là pour remonter les erreurs du client.

Une dernière vérification de la validité de la réponse et vous pourrez utiliser le body pour vos fonctionnalités !

private fun executeCall() {  
    launch(Dispatchers.Main) {  
        try {  
            val response = ApiClient.apiService.getPostById(1)  
      
            if (response.isSuccessful && response.body() != null) {  
                val content = response.body()  
                //do something  
            } else {  
                Toast.makeText(  
                    this@MainActivity,  
                    "Error Occurred: ${response.message()}",  
                     Toast.LENGTH_LONG  
                ).show()  
            }  
      
        } catch (e: Exception) {  
            Toast.makeText(  
                this@MainActivity,  
                "Error Occurred: ${e.message}",  
                Toast.LENGTH_LONG  
            ).show()  
        }
    }    
}

Et voilà ! Vous savez désormais comment implémenter Retrofit dans un projet Android via Kotlin ! À vous le gain de temps, le code plus clair et tout aussi performant.

À très bientôt pour de nouveaux articles Android !