Kotlin Coroutines are expanding into the areas of Networking. With the new release of Retrofit 2.6.0, we can now add the suspend modifier to our Retrofit Service interface methods without passing any adapter for Deferred type. This allows us to express the asynchrony of HTTP requests in an idiomatic fashion for the language.



This article assumes you have the basic familiarity with Retrofit and Kotlin Coroutines.

Add Dependencies

First, in order to use Retrofit for built-in support suspend keyword, we need to add library in our app-level build.gradle file. Besides this, we also need to add Kotlin Coroutines dependency.

Add the following dependencies into your build.gradle file.

dependencies { // retrofit dependency implementation 'com.squareup.retrofit2:retrofit:2.6.0' // kotlin coroutines dependencies implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0-alpha' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.0-alpha' }

Once you’ve add the dependencies hit the Sync Now and everything should be fine without any kind of gradle error.

The Retrofit 2 Service

With the libraries included, now let’s get to the Retrofit service interface definition.

interface ApiService { @GET(value = "user") suspend fun getUserAsync(@Query(value = "id") userId: Long): User }

We define a service interface called ApiService. Since our only focus on how to define a method with suspend keyword. That’s why I only define a single method matching with the end-point.

Note: If you look at the return type of getUserAsync, you may notice that we’re only returning the User object. Under the hood, Retrofit defines our method fun getUserAsync(.....): Call<User> and then invoked with Call.enqueue on it. Currently in this release of Retrofit 2.6.0 only support non-null response types. Follow this issue for nullable support type.

Perform UserAsync Fetching

Testing the Retrofit suspend method is no different from other functions. Let’s see an example of it.

class MyViewModel : ViewModel() { private val job = SupervisorJob() private val coroutineContext = Dispatchers.IO + job private val serviceApi = // get instance fun fetchUser(id: Long) { viewModelScope.launch(coroutineContext) { val user = serviceApi.getUserAsync("userId" = id) // handle fetched user..... } } }

The code above is pretty straight forward. If you’re a little bit familiar with kotlin coroutines then you probably heard of ” The suspend method can only be a call from another suspend block“. That’s why we’re calling the getUserAsync method of ApiService inside the launch builder.

Under the hood Retrofit library fetch the User for us and return it. Pretty Simple 👍!

Return Complete Response With Body

You may need to access the response metadata and with the above getUserAsync return type that may not be possible. So, we need to change the return type with Response<User> .

import retrofit2.Response interface ApiService { @GET(value = "user") suspend fun getUserAsync(@Query(value = "id") userId: Long): Response<User> }

Now with new return type we can check what the status code of our request, is the request is successful or not.

class MyViewModel : ViewModel() { private val job = SupervisorJob() private val coroutineContext = Dispatchers.IO + job private val serviceApi = // get instance fun fetchUser(id: Long) { viewModelScope.launch(coroutineContext) { val response = serviceApi.getUserAsync("userId" = id) if(response.isSuccessful) val user = response.body // handle fetched user else if(response.code() == 401) // handle un-authorization else // handle request failed } } }

Alright, guys, this was from this article. Hope you learn something, either a little Retrofit 2.6.0 new feature or something about Kotlin.

If you like to explore what’s more came with the new release see the change log on GitHub.

Thank you for being here and keep reading…