Retrofit with Kotlin Flow

Authors
  • Amit Shekhar
    Name
    Amit Shekhar
    Published on
Retrofit with Kotlin Flow

I am Amit Shekhar, Founder @ Outcome School, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

I teach AI and Machine Learning, and Android at Outcome School.

Join Outcome School and get high paying tech job:

In this blog, we will learn how to use Retrofit with Kotlin Flow in Android. We will learn to write the code inside the ViewModel with Kotlin Flow that follows a basic MVVM Architecture.

This blog is a part of the series I have written on Flow API in Kotlin:

I will be using the following project for the implementation part. The project follows a basic MVVM Architecture for simplicity. You can find the complete code for the implementation mentioned in this blog in the project itself.

GitHub Project: Learn Kotlin Flow

First, we need to set up our dependencies for the Retrofit as below:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

Note: Always check for the latest available version.

As I am using the Gson to parse JSON into Java and Kotlin classes, I have added the dependency for the Gson. You can add based on your requirement.

Now, create the data class ApiUser as below:

data class ApiUser(
    @SerializedName("id")
    val id: Int = 0,
    @SerializedName("name")
    val name: String = "",
    @SerializedName("email")
    val email: String = "",
    @SerializedName("avatar")
    val avatar: String = ""
)

Now, we need to create the ApiService interface required for Retrofit.

interface ApiService {

    @GET("users")
    suspend fun getUsers(): List<ApiUser>

    @GET("more-users")
    suspend fun getMoreUsers(): List<ApiUser>

    @GET("error")
    suspend fun getUsersWithError(): List<ApiUser>

}

Note: We have used suspend keyword.

After this, we will be needing a class RetrofitBuilder which will be a Singleton.

object RetrofitBuilder {

    private const val BASE_URL = "https://5e510330f2c0d300147c034c.mockapi.io/"

    private fun getRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }

    val apiService: ApiService = getRetrofit().create(ApiService::class.java)

}

Then, we will create an interface ApiHelper.

interface ApiHelper {

    fun getUsers(): Flow<List<ApiUser>>

    fun getMoreUsers(): Flow<List<ApiUser>>

    fun getUsersWithError(): Flow<List<ApiUser>>

}

Note: The return type is Flow.

After that, we will create a class ApiHelperImpl that implements the ApiHelper interface.

class ApiHelperImpl(private val apiService: ApiService) : ApiHelper {

    override fun getUsers() = flow {
        emit(apiService.getUsers())
    }

    override fun getMoreUsers() = flow {
        emit(apiService.getMoreUsers())
    }

    override fun getUsersWithError() = flow {
        emit(apiService.getUsersWithError())
    }

}

Here, we must understand that the return type is Flow. Also, we are using a flow builder and emitting the item as per the requirement.

Once we've done that, we can create the instance of ApiHelper as below:

val apiHelper = ApiHelperImpl(RetrofitBuilder.apiService)

Finally, we can pass this instance wherever required, for example to the ViewModel, and make the network call to get the users from the network as below:

class SingleNetworkCallViewModel(private val apiHelper: ApiHelper, private val dbHelper: DatabaseHelper) : ViewModel() {

    init {
        fetchUsers()
    }

    private fun fetchUsers() {
        viewModelScope.launch {
            apiHelper.getUsers()
                .flowOn(Dispatchers.IO)
                .catch { e ->
                    // handle exception
                }
                .collect {
                    // list of users from the network
                }
        }
    }

}

This way, we are able to fetch the data from the network using Retrofit with Kotlin Flow in Android.

I must mention that you can learn much more from the GitHub repository that I mentioned above in this blog. You can learn the following:

  • Making network calls in series using Retrofit with Kotlin Flow.
  • Making multiple network calls in parallel using Retrofit with Kotlin Flow.

This is how we can use Retrofit with Kotlin Flow in Android.

Prepare yourself for Android Interview: Android Interview Questions

That's it for now.

Thanks

Amit Shekhar
Founder @ Outcome School

You can connect with me on:

Follow Outcome School on:

Read all of our high-quality blogs here.