Networking with Retrofit
Why a networking library?
Almost every real app talks to a server: logging in, fetching a feed, posting data. You could use raw sockets, but that is painful. Retrofit (by Square) is the standard library that turns a REST API into a simple Kotlin interface, and pairs with a converter (Moshi or Gson) to parse JSON into objects automatically.
Step 1: the data model
data class User(val id: Int, val name: String, val email: String)
Step 2: describe the API
interface ApiService {
@GET("users")
suspend fun getUsers(): List<User>
@GET("users/{id}")
suspend fun getUser(@Path("id") id: Int): User
@POST("users")
suspend fun createUser(@Body user: User): User
}
Each annotation (@GET, @POST, @Path, @Body) maps a Kotlin function to an HTTP request. The suspend keyword means it runs off the main thread.
Step 3: build Retrofit
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(MoshiConverterFactory.create())
.build()
val api = retrofit.create(ApiService::class.java)
Step 4: call it safely
viewModelScope.launch {
try {
val users = api.getUsers() // background thread
_uiState.value = UiState.Success(users)
} catch (e: IOException) {
_uiState.value = UiState.Error("No internet")
} catch (e: HttpException) {
_uiState.value = UiState.Error("Server error ${e.code()}")
}
}
Don’t forget the permission
<uses-permission android:name="android.permission.INTERNET" />
Common mistakes
- Calling the network on the main thread — always use
suspend+ a coroutine. - Not handling errors — networks fail; wrap calls in try/catch and show a message.
- Forgetting the trailing slash in
baseUrl(Retrofit requires it).
Summary: Describe the API in an interface, build Retrofit with a JSON converter, call suspend functions inside a coroutine, and always handle errors.