Most Android apps communicate with remote servers to fetch data, submit forms, or sync user content. REST APIs expose resources over HTTP, and libraries like Retrofit and Volley simplify making those requests from Kotlin.
REST (Representational State Transfer) is an architectural style where resources (users, posts, products) are identified by URLs and manipulated using HTTP methods. Responses are usually JSON.
REST resource design
Resource HTTP Method Endpoint
─────────────────────────────────────────
List posts GET /posts
Get one post GET /posts/{id}
Create post POST /posts
Update post PUT /posts/{id}
Delete post DELETE /posts/{id}
Sample JSON response
JSON — GET /posts/1{
"userId": 1,
"id": 1,
"title": "Hello REST API",
"body": "Learning Android networking with Kotlin."
}
Internet permission
XML — AndroidManifest.xml<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Practice API: Use free test endpoints like JSONPlaceholder or ReqRes while learning — no backend setup required.
3Retrofit
Retrofit is a type-safe HTTP client for Android. You define an interface with annotations, and Retrofit generates the request code. It integrates cleanly with coroutines, Gson/Moshi, and OkHttp.
Kotlin — ApiService.ktinterface ApiService {
@GET("posts")
suspend fun getPosts(): List<Post>
@GET("posts/{id}")
suspend fun getPost(@Path("id") postId: Int): Post
@POST("posts")
suspend fun createPost(@Body post: Post): Post
@PUT("posts/{id}")
suspend fun updatePost(@Path("id") id: Int, @Body post: Post): Post
@DELETE("posts/{id}")
suspend fun deletePost(@Path("id") id: Int): Response<Unit>
}
data class Post(
val userId: Int,
val id: Int? = null,
val title: String,
val body: String
)
Retrofit instance
Kotlin — RetrofitClient.ktobject RetrofitClient {
private const val BASE_URL = "https://jsonplaceholder.typicode.com/"
private val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
4Volley
Volley is Google's HTTP library for Android. It handles request queuing, caching, and image loading. While Retrofit is preferred for REST APIs, Volley remains useful for simple GET/POST requests.
Never block the main thread with network I/O. Use coroutines with Retrofit suspend functions, or callbacks with Volley. The Repository pattern keeps networking logic out of Activities and Fragments.
Repository pattern
Kotlin — PostRepository.ktclass PostRepository(
private val api: ApiService = RetrofitClient.api
) {
suspend fun getPosts(): Result<List<Post>> = safeApiCall {
api.getPosts()
}
suspend fun getPost(id: Int): Result<Post> = safeApiCall {
api.getPost(id)
}
suspend fun createPost(title: String, body: String): Result<Post> = safeApiCall {
api.createPost(Post(userId = 1, title = title, body = body))
}
}
ViewModel calling repository
Kotlin — PostViewModel.ktclass PostViewModel : ViewModel() {
private val repository = PostRepository()
private val _posts = MutableLiveData<List<Post>>()
val posts: LiveData<List<Post>> = _posts
private val _loading = MutableLiveData<Boolean>()
val loading: LiveData<Boolean> = _loading
private val _error = MutableLiveData<String?>()
val error: LiveData<String?> = _error
fun loadPosts() {
viewModelScope.launch {
_loading.value = true
_error.value = null
repository.getPosts()
.onSuccess { _posts.value = it }
.onFailure { _error.value = it.message }
_loading.value = false
}
}
}
API responses arrive as JSON strings. Retrofit with Gson/Moshi converts them into Kotlin data classes automatically. For manual parsing, use JSONObject or JSONArray.
Data class mapping with Gson
Kotlin — User.ktdata class User(
val id: Int,
val name: String,
val email: String,
@SerializedName("avatar_url") val avatarUrl: String? = null
)
Kotlin — Nested data classesdata class ApiResponse(
val data: PostData
)
data class PostData(
val id: Int,
val attributes: PostAttributes
)
data class PostAttributes(
val title: String,
val published: Boolean
)
Manual parsing with org.json
Kotlin — Parse JSONArray manuallyfun parsePosts(jsonString: String): List<Post> {
val posts = mutableListOf<Post>()
val jsonArray = JSONArray(jsonString)
for (i in 0 until jsonArray.length()) {
val obj = jsonArray.getJSONObject(i)
posts.add(
Post(
userId = obj.getInt("userId"),
id = obj.getInt("id"),
title = obj.getString("title"),
body = obj.getString("body")
)
)
}
return posts
}
Query parameters and headers
Kotlin — Retrofit query and headerinterface ApiService {
@GET("users")
suspend fun searchUsers(
@Query("page") page: Int,
@Query("limit") limit: Int = 10
): List<User>
@GET("profile")
suspend fun getProfile(
@Header("Authorization") token: String
): User
}
7Error Handling
Network calls can fail for many reasons — no internet, timeouts, server errors, or invalid JSON. Wrap API calls in a safe helper and map HTTP errors to user-friendly messages.
safeApiCall wrapper
Kotlin — NetworkUtils.ktsuspend fun <T> safeApiCall(apiCall: suspend () -> T): Result<T> {
return try {
if (!isNetworkAvailable()) {
return Result.failure(NetworkException("No internet connection"))
}
Result.success(apiCall())
} catch (e: HttpException) {
Result.failure(mapHttpError(e))
} catch (e: IOException) {
Result.failure(NetworkException("Connection failed. Check your network."))
} catch (e: Exception) {
Result.failure(e)
}
}
fun mapHttpError(exception: HttpException): Exception {
return when (exception.code()) {
400 -> ApiException("Invalid request")
401 -> ApiException("Please log in again")
403 -> ApiException("Access denied")
404 -> ApiException("Resource not found")
500 -> ApiException("Server error. Try again later.")
else -> ApiException("Error ${exception.code()}: ${exception.message()}")
}
}
class NetworkException(message: String) : Exception(message)
class ApiException(message: String) : Exception(message)
Check network connectivity
Kotlin — isNetworkAvailable()fun Context.isNetworkAvailable(): Boolean {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
Kotlin — Show error in UIsealed class UiState<out T> {
object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(val message: String, val retry: (() -> Unit)? = null) : UiState<Nothing>()
}
// In Fragment/Activity:
when (val state = viewModel.uiState.value) {
is UiState.Loading -> showProgress()
is UiState.Success -> showData(state.data)
is UiState.Error -> {
hideProgress()
binding.errorText.text = state.message
binding.btnRetry.setOnClickListener { state.retry?.invoke() }
}
}
8Hands-On Exercises
1
Add INTERNET permission and study the HTTP methods table — match each CRUD action to GET, POST, PUT, DELETE.
2
Explore JSONPlaceholder in a browser. Understand REST API endpoints for /posts and /users.
3
Set up Retrofit with Gson converter. Create an ApiService interface and fetch the posts list.
4
Make the same GET request using VolleyStringRequest and compare the callback approach.
5
Build a Repository + ViewModel flow. Display posts in a RecyclerView with loading indicator.
6
Parse a nested JSON response into Kotlin data classes. Map a field with @SerializedName.
7
Implement error handling: show "No internet" when offline, map 404/500 codes, and add a Retry button.
REST API & Networking MCQ Practice
10 Basic MCQs10 Advanced MCQs
10 Basic REST API & Networking MCQs
1
REST stands for?
ARemote Execution Service Tool
BRepresentational State Transfer
CReactive Event Stream Transport
DRuntime Embedded SQL Template
Explanation: REST is an architectural style for networked APIs using HTTP.
2
HTTP GET typically?
ASigns APK
BDeletes database
CRetrieves data from server
DStarts Service
Explanation: GET is idempotent and used for reading resources.
3
Retrofit is?
ACamera library
BJSON database
CLayout manager
DType-safe HTTP client for Android/Java
Explanation: Square's Retrofit converts REST API into Java/Kotlin interfaces.
4
HTTP POST used for?
ACreating or submitting data
BOnly reading cache
CGradle sync
DLayout inflation
Explanation: POST sends body data to create/update resources.
5
JSON in API responses is?
ABinary dex format
BJavaScript Object Notation text format
CSQL schema
DManifest XML
Explanation: Lightweight data interchange format parsed into objects.
6
INTERNET permission is?
AOptional for Retrofit
BRuntime dangerous permission
CRequired in manifest for network calls
DReplaced by WiFi permission
Explanation: Normal permission declared in AndroidManifest.xml.
7
HTTP 404 means?
AUnauthorized
BSuccess
CServer error always
DResource not found
Explanation: Client error — URL or resource ID doesn't exist.
8
Base URL in Retrofit set via?
ARetrofit.Builder().baseUrl(...)
Bstrings.xml only
CRoom database
DIntent filter
Explanation: All @GET/@POST paths append to base URL.
9
Volley is?
ASQL ORM
BGoogle HTTP library with request queue
CUI widget
DBluetooth stack
Explanation: Volley suits small frequent requests; Retrofit preferred for REST APIs.
10
HTTPS provides?
ANo certificates needed
BFaster than HTTP always
CEncrypted HTTP via TLS/SSL
DLocalhost only
Explanation: Always use HTTPS for production API calls.
10 Advanced REST API & Networking MCQs
11
@GET("users/{id}") path param?
A@Query only
B@Path("id") in method parameter
C@Body required
D@Header id
Explanation: @Path maps URL template segments to method args.
12
OkHttp Interceptor used for?
ASQLite migration
BLayout preview
CLogging, auth headers, retry logic
DCamera bind
Explanation: Interceptors modify requests/responses in the chain.
13
Retrofit with coroutines uses?
AMain thread blocking
BAsyncTask
CHandler only
Dsuspend fun on service interface
Explanation: CallAdapter converts Response to suspend or Flow.
14
HTTP 401 indicates?
AUnauthorized — auth required or invalid
BSuccess
CNot found
DTimeout only
Explanation: Handle with token refresh or login redirect.
15
Connection timeout handled by?
AManifest merge
BOkHttp client timeout settings
CViewBinding
DRecyclerView
Explanation: connectTimeout, readTimeout, writeTimeout on OkHttpClient.
16
@Query annotation?
APath segment
BJSON body field
CAppends ?key=value query parameters
DGradle property
Explanation: Example: @Query("page") page: Int for pagination.
17
NetworkOnMainThreadException means?
AMissing icon
BServer down
CInvalid JSON
DNetwork call on UI thread
Explanation: Use coroutines, Retrofit enqueue, or background thread.
18
Retrofit GsonConverterFactory?
AAuto JSON to Kotlin/Java objects
BEncrypts traffic
CCaches images
DGPS location
Explanation: Converter parses response body into model classes.
19
REST idempotency — PUT vs POST?
AIdentical
BPUT idempotent update; POST creates new
CPOST always idempotent
DPUT creates only
Explanation: Repeating PUT to same URI has same effect.
20
Certificate pinning?
AUse HTTP
BDisable TLS
CTrust only specific server certificates
DRoom feature
Explanation: Mitigates MITM — pin cert in OkHttp CertificatePinner.
Click an option to select, then check answers.
REST API & Networking Interview Q&A
15 topic-focused questions for interviews and revision.
1What is a REST API?easy
Answer: HTTP-based interface using resources (URLs) and methods (GET/POST/PUT/DELETE) exchanging JSON or XML.
2Retrofit setup steps.easy
Answer: Add dependencies, define data classes, create interface with @GET/@POST, build Retrofit with baseUrl and converters, create service instance.
3Difference GET vs POST.easy
Answer: GET retrieves data without body; POST submits data in body to create or process.
4Handle API errors in Retrofit.medium
Answer: Check response.isSuccessful; parse errorBody; use try/catch for IOException; map HTTP codes to user messages.