Retrofit with Kotlin Flow
- Authors
- Name
- Amit Shekhar
- Published on
I am Amit Shekhar, Co-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.
Join Outcome School and get high paying tech job: Outcome School
Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out Android Interview Questions and Answers.
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:
- Mastering Flow API in Kotlin
- Creating Flow Using Flow Builder in Kotlin
- Terminal Operators in Kotlin Flow
- Cold Flow vs Hot Flow
- StateFlow and SharedFlow
- Long-running tasks in parallel with Kotlin Flow
- Retry Operator in Kotlin Flow
- Retrofit with Kotlin Flow - YOU ARE HERE
- Room Database with Kotlin Flow
- Kotlin Flow Zip Operator for Parallel Multiple Network Calls
- Instant Search Using Kotlin Flow Operators
- Exception Handling in Kotlin Flow
- callbackFlow - Callback to Flow API in Kotlin
- Unit Testing ViewModel with Kotlin Flow and StateFlow
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
Co-Founder @ Outcome School
You can connect with me on:
Follow Outcome School on: