Retrofit, what is it?
Most mobile applications consume REST JSON APIs to retrieve all the data necessary for their operation.
Retrofit is today one of the easiest ways to implement calls to REST webservices .
This is a REST client developed by Jake Wharton as well as all of Square's staff. This library is itself based on the OKHttp REST client (further developed by Square!) And makes it easier and faster to implement network requests on Android (Java or Kotlin).
Retrofit thus avoids us manually installing all the parts necessary for the execution of a request, such as for example the management of JSON responses or the creation of an AsyncTask .
This allows a significant time saving and a clearer code for equivalent performance .
Since then, Retrofit 2.6 supports the use of coroutines . This makes it possible to no longer use a callback or the inqueue function.
How to implement Retrofit in an Android project via Kotlin?
For this example, we'll be using https://jsonplaceholder.typicode.com/ , which is a free API providing test data.
Add permissions in AndroidManifest.xml
"INTERNET" permission is required to call APIs in an Android application.
"ACCES_NETWORK_STATE" identifies the status of the device's internet connection.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
Implementation of the necessary libraries
To install Retrofit, you need at least Java 8+ or Android API 21+ .
You will then need to install the following dependencies by entering them in the build.gradle file under "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: creation of a Retrofit instance
The Retrofit client must be configured with a server URL (BASE_URL) as well as a request converter. This converter will automatically convert the JSON response into objects. Here we are using the Gson converter . Do not forget the lazy keyword , in order not to duplicate instances of 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: creation of an interface that groups together the different endpoints
We find, in the form of annotations, the method and the route. You will also have to specify the type of response so that Gson can deserialize it.
Note the need to specify the type of parameter with the @Path, @Query and @Body annotations
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> @GET("posts/{num}") suspend fun getPostById(@Path("num") num : Int): Response @GET("comments") suspend fun getCommentsByPost(@Query("postId") postId : Int): Response> @POST("posts") suspend fun createPost(@Body post: Post): Response }
The following methods are available:
- @GET
- @POST
- @PUT
- @DELETE
- @PATCH
The @HEADER annotation is also available here to define one or more headers on an endpoint.
The models
Here, we create the models via data classes in order to deserialize the responses and store our data. Importantly, each field of each model must be identical to the response (name and type) so that the deserialization of the latter works.
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 )
A use case in mainActivity
For this part, we will use Coroutine. Coroutine is a utility from Kotlin for performing asynchronous tasks. For this we need to implement CoroutineScope which will indicate where the coroutine should send data. Here, for this example, it will be in MainScope if we want to modify the display of the mainActivity.
Let's start by creating a new coroutine with the launch function and restricting it to the main thread with Dispachers.Main.
The try / catch is there to report client errors.
A final check of the validity of the answer and you can use the body for your functionalities!
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() } } }
And There you go ! You now know how to implement Retrofit in an Android project via Kotlin! You save time, the code is clearer and just as efficient.
See you soon for new Android articles!
Sahil is a highly skilled and dedicated Salesforce Certified Platform Developer with a passion for creating efficient and innovative solutions within the Salesforce ecosystem. With an insatiable curiosity and a relentless drive for excellence, he has become a go-to expert in developing custom applications and functionalities on the Salesforce platform.
Comments are closed.