Skip to content

Android Retrofit Networking

★★★★★ Intermediate

Retrofit is the standard HTTP client for Android, converting REST API definitions into Kotlin interfaces. Combined with Gson for JSON parsing and OkHttp for transport, it provides type-safe API access with minimal boilerplate.

Key Facts

  • Retrofit converts annotated Kotlin interfaces into HTTP client implementations
  • @GET, @POST, @PUT, @DELETE define HTTP methods on interface functions
  • @Path("id") substitutes into URL path segments ({id})
  • @Query("name") appends URL query parameters
  • GsonConverterFactory handles JSON serialization/deserialization
  • OkHttpClient with logging interceptor enables network debugging
  • Returns can be Observable<T> (RxJava), Call<T>, or suspend functions (coroutines)

Patterns

Data Models

data class GeckoCoin(
    val id: String,
    val symbol: String,
    val name: String,
    val image: String,
    val current_price: Float,
    val market_cap: Float,
    val market_cap_rank: Int,
    val total_volume: Float,
    val price_change_percentage_24h: Float
)

data class GeckoCoinChart(
    var prices: List<List<Float>>
)

API Interface

import retrofit2.http.*

interface CoinGeckoApi {
    @GET("coins/markets")
    fun getCoinMarket(
        @Query("vs_currency") vs: String = "usd",
        @Query("per_page") perPage: Int = 100,
        @Query("sparkline") sparkline: Boolean = false,
        @Query("order") order: String = "market_cap_desc"
    ): Observable<List<GeckoCoin>>

    @GET("coins/{id}/market_chart")
    fun getCoinMarketChart(
        @Path("id") id: String,
        @Query("vs_currency") vsCurrency: String = "usd",
        @Query("days") days: String = "max"
    ): Observable<GeckoCoinChart>
}

Retrofit Annotations Reference

Annotation Purpose Example
@GET("path") GET request @GET("coins/markets")
@POST("path") POST request @POST("users")
@PUT("path") PUT request @PUT("users/{id}")
@DELETE("path") DELETE request @DELETE("users/{id}")
@Path("name") URL path parameter {id} in URL
@Query("name") Query parameter ?key=value
@QueryMap Multiple query params Map<String, String>
@Body Request body For POST/PUT

Retrofit Builder

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(
        HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY)
    )
    .connectTimeout(60, TimeUnit.SECONDS)
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.coingecko.com/api/v3/")
    .addConverterFactory(GsonConverterFactory.create(gson))
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .client(okHttpClient)
    .build()

val apiService = retrofit.create(CoinGeckoApi::class.java)

With Dagger 2 Module

@Module
class RestModule {
    @Provides
    @Singleton
    fun provideGson(): Gson = GsonBuilder().setLenient().create()

    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient =
        OkHttpClient.Builder()
            .addInterceptor(
                HttpLoggingInterceptor()
                    .setLevel(HttpLoggingInterceptor.Level.BODY)
            )
            .connectTimeout(60, TimeUnit.SECONDS)
            .build()

    @Provides
    @Singleton
    fun provideRetrofit(gson: Gson, okHttpClient: OkHttpClient): Retrofit =
        Retrofit.Builder()
            .baseUrl("https://api.coingecko.com/api/v3/")
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpClient)
            .build()

    @Provides
    @Singleton
    fun provideApiService(retrofit: Retrofit): CoinGeckoApi =
        retrofit.create(CoinGeckoApi::class.java)
}

Retrofit vs URLSession (iOS) Comparison

Feature Retrofit (Android) URLSession (iOS)
Definition Annotated interface Inline URL construction
JSON parsing Gson converter JSONDecoder (Codable)
Type safety Compile-time from annotations Runtime from Decodable
HTTP client OkHttp Built-in URLSession
Async RxJava / Coroutines async/await

build.gradle Dependencies

implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.google.code.gson:gson:2.10.0"
implementation "com.squareup.okhttp3:okhttp:4.11.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.11.0"

Gotchas

  • Base URL must end with / or Retrofit throws an exception
  • @Path parameters are URL-encoded by default; use @Path(encoded = true) for pre-encoded values
  • Logging interceptor at Level.BODY logs full request/response bodies - disable in production for security
  • Gson uses field names by default for JSON keys; use @SerializedName("json_key") for custom mapping
  • Network calls on the main thread cause NetworkOnMainThreadException - always use background dispatchers
  • Observable<T> requires RxJava2CallAdapterFactory; for coroutines, use suspend fun return types instead

See Also