Retrofit with Kotlin Flow
- Authors
- Name
- Amit Shekhar
- Published on
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:
- 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
Founder @ Outcome School
You can connect with me on:
Follow Outcome School on:
