Retrofit — what it is, HTTP library, and usage in applications

Author: IT Sectr Published: 2026-05-04 Reading time: 8 min

Retrofit is a type-safe HTTP client for Android, developed by Square in Java. The library allows you to define REST APIs through Java interfaces with annotations, automatically converting HTTP responses into Java objects. According to the Retrofit repository on GitHub, the project is used by more than 42,000 projects worldwide. The library remains the standard for network requests in Android development.

Key Takeaways

  • Retrofit — a type-safe HTTP client from Square for Android in Java and Kotlin
  • Annotations @GET, @POST, @PUT and @DELETE define endpoints directly in the interface
  • Converters Gson, Moshi and Jackson automatically transform JSON into objects
  • Adapters for Kotlin coroutines and RxJava provide asynchronous execution
  • Interceptors in OkHttp allow logging requests and adding headers

What is Retrofit?

Retrofit is a library for making HTTP requests in Android applications, developed by Square. It provides a declarative approach to defining REST APIs through Java interfaces with annotations, making network interaction code clean and predictable.

The core idea of Retrofit is that the developer describes the API as an interface with methods and annotations, and the library generates the implementation automatically. This approach ensures that all endpoints are typed, and errors in URLs or parameters are detected at compile time rather than at runtime.

Retrofit supports all popular HTTP methods and data formats. The library is actively maintained by Square and the community: new releases come out regularly, and the current version 2.11 includes support for Java 17 and Kotlin 2.0. Retrofit remains the most popular HTTP client for Android.

Retrofit runs on top of OkHttp — an efficient HTTP client also from Square. This combination provides caching, request interception, and connection management at the transport protocol level. The library supports both synchronous and asynchronous calls.

Since its first release in 2013, Retrofit has gone through several major updates. The current version Retrofit 2 has been completely rewritten based on experience with the first version and offers a more flexible system of converters and adapters for asynchrony.

Retrofit's architecture follows the principle of separation of concerns: the interface defines only the API contract, converters handle serialization, and adapters manage asynchrony. This allows replacing any component without changing the rest of the code. For example, you can switch from Gson to Moshi without changing endpoint definitions.

Key Features of Retrofit

Retrofit provides a set of features that cover virtually all network interaction scenarios in mobile applications. The key advantage is the declarative style of API definition.

Declarative Endpoint Annotations

Annotations @GET, @POST, @PUT, @PATCH, @DELETE and @HTTP allow you to specify the HTTP method and URL template directly in the interface. Path parameters are set via @Path, query parameters via @Query, and the request body via @Body. This approach makes the application's API layer fully typed.

Converters for Serialization

Converters transform HTTP responses into Java objects and vice versa. Retrofit supports Gson, Moshi, Jackson, Protobuf and Wire. The developer connects the required converter via Converter.Factory, and the library automatically applies it to all requests and responses.

Adapters for Asynchrony

Adapters CallAdapter allow changing the return type of API methods. Instead of the standard Call, you can use Observable for RxJava, Deferred for Kotlin coroutines, or LiveData. This integrates network requests with the chosen application architecture.

Dynamic URLs and Headers

Dynamic URLs are set via @Url annotations, allowing you to pass the endpoint at runtime. Headers can be specified statically via @Headers or dynamically via the @Header parameter. For global headers across all requests, an OkHttp interceptor is used, which adds headers to each outgoing request.

How Does Retrofit Work?

Retrofit works in three stages: defining the API interface, creating a Retrofit instance, and executing the request. The library generates the interface implementation at runtime based on annotations and converters.

Request Lifecycle

When an API method is called, Retrofit creates a Request object based on the annotations and arguments. The request is passed to OkHttp for execution. After receiving the response, the library passes it to Converter.Factory for transformation into the required type. CallAdapter wraps the result in an asynchronous wrapper. Each stage can be customized.

kotlin
interface ApiService {
    @GET("users/{id}")
    suspend fun getUser(@Path("id") id: Int): User
}

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val api = retrofit.create(ApiService::class.java)

Installation and Setup of Retrofit

Installation of Retrofit is done through Gradle — the standard Android build system. The library is distributed via Maven Central and requires adding several dependencies to the project's build.gradle.

Adding Dependencies

In the build.gradle file (module level), add dependencies for Retrofit, Gson converter, and OkHttp. It is recommended to extract library versions into variables in the root build.gradle for centralized management. Retrofit 2 requires a minimum of Android API 21.

groovy
dependencies {
    implementation "com.squareup.retrofit2:retrofit:2.11.0"
    implementation "com.squareup.retrofit2:converter-gson:2.11.0"
    implementation "com.squareup.okhttp3:okhttp:4.12.0"
    implementation "com.squareup.okhttp3:logging-interceptor:4.12.0"
}

Creating a Retrofit Instance

A Retrofit instance is created via Builder. Required parameters: baseUrl and ConverterFactory. It is recommended to use a singleton for Retrofit and OkHttpClient to avoid creating redundant connections. Adding a logging-interceptor simplifies debugging network requests during development.

For Kotlin projects, it is recommended to use suspend functions in the API interface instead of Call types. This simplifies the code and allows using structured concurrency of coroutines. When switching from Call to suspend, you only need to change the return type in the interface — the rest of the code adapts automatically.

Retrofit Usage Examples

The examples below demonstrate typical scenarios of working with Retrofit in Android applications: from a simple GET request to uploading a file to the server.

GET Request with Query Parameters

A simple GET request with query string parameters is a basic operation. The @Query annotation adds parameters to the URL automatically, and the suspend function allows calling the request from a coroutine without blocking the main thread.

kotlin
interface UserApi {
    @GET("users")
    suspend fun getUsers(
        @Query("page") page: Int,
        @Query("limit") limit: Int = 20
    ): List<User>
}

val users = api.getUsers(page = 1)

POST Request with JSON Body

A POST request with a JSON body uses the @Body annotation to pass the object. GsonConverterFactory automatically serializes the User object into JSON. Kotlin coroutines ensure the request is executed in the background thread without Callback interfaces.

kotlin
interface UserApi {
    @POST("users")
    suspend fun createUser(@Body user: User): User
}

val user = User(name = "Anna Ivanova", email = "anna@example.com")
val created = api.createUser(user)

File Upload via Multipart

The @Multipart annotation with @Part allows uploading files to the server. Retrofit automatically forms a multipart request with the required headers. OkHttp manages upload progress through RequestBody, allowing you to display an indicator to the user.

kotlin
interface FileApi {
    @Multipart
    @POST("upload")
    suspend fun uploadImage(
        @Part file: MultipartBody.Part
    ): UploadResponse
}

val body = "image.jpg".toRequestBody("image/jpeg".toMediaTypeOrNull())
val part = MultipartBody.Part.createFormData("file", "image.jpg", body)

Error Handling and Interceptors in Retrofit

Error handling in Retrofit is built on a combination of OkHttp mechanisms and Kotlin coroutines. OkHttp interceptors allow logging requests, adding authentication headers, and handling errors before they reach the application code.

For centralized error handling, a wrapper around API calls is often created as a sealed class Result. Such a class has two subclasses: Success with data and Error with an exception. The ViewModel receives a unified result and can display the corresponding user interface state without duplicating error handling code in each function.

Interceptors come in two types: application interceptors modify the request before it is sent to the server, and network interceptors work with the response after it is received. For example, an interceptor can automatically refresh the access token upon receiving a 401 and retry the request with the new token without developer involvement.

Logging Requests via Interceptor

The logging interceptor HttpLoggingInterceptor is an indispensable tool for debugging network requests. It outputs the request method, URL, headers, body, and response code to Logcat. The logging level can be configured: BASIC for minimal information, HEADERS for headers, or BODY for full content. In production, it is recommended to use BASIC or disable logging entirely.

Interceptors in OkHttp are divided into two types: application interceptors for modifying the request and network interceptors for working with raw network data. The logging interceptor automatically outputs request and response details to Logcat.

Error handling at the coroutine level is done via try-catch around the suspend function call. Retrofit returns errors as HttpException for 4xx and 5xx codes, UnknownHostException when there is no network, and SocketTimeoutException when a timeout occurs. It is recommended to use a sealed class Result for unified handling.

Frequently Asked Questions

How is Retrofit different from OkHttp?

Retrofit is a high-level wrapper over OkHttp. OkHttp performs low-level HTTP operations, while Retrofit adds declarative annotations, converters, and adapters. Typically, projects use both libraries together.

How to handle errors in Retrofit with coroutines?

Errors are handled via try-catch around the suspend call. It is recommended to use a Result class to return either successful data or an error. This avoids multiple catch blocks in each ViewModel.

What converters does Retrofit support?

Retrofit supports Gson, Moshi, Jackson, Protobuf, Wire, Simple XML, and Scalars. Each converter is connected via Converter.Factory. The most popular are GsonConverterFactory and MoshiConverterFactory.

Can I use Retrofit with Ktor instead of OkHttp?

No, Retrofit is tightly coupled to OkHttp and does not support other HTTP clients. For multiplatform projects in Kotlin, use Ktor, which works on all platforms, including iOS and JS.

How to configure timeout in Retrofit?

Timeout is configured through OkHttpClient. Set the connectTimeout, readTimeout, and writeTimeout properties when creating the client, then pass it to Retrofit.Builder.client(). Default values are 10 seconds.

Summary

  • Retrofit — the standard HTTP client for Android with declarative API definition through annotations
  • The library runs on top of OkHttp and supports Gson, Moshi, and Jackson for serialization
  • Annotations @GET, @POST, @PUT, and @DELETE cover all typical HTTP methods
  • Adapters for Kotlin coroutines and RxJava provide asynchronous request handling
  • OkHttp interceptors allow logging requests and adding authentication headers
  • Installation via Gradle with adding retrofit, converter, and okhttp dependencies
  • Error handling is done via try-catch in coroutines with Result types for unification

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also