Sparround

Retrofit + OkHttp: quruluş, interceptor-lər, error handling

OkHttp — HTTP client-dir: connection pool, TLS, cache, retry, HTTP/2 onun işidir. Retrofit — OkHttp üstündə tip-təhlükəsiz REST qatı: interfeys metodlarını HTTP sorğularına çevirir.

Retrofit-in üç açar hissəsi:

  • Annotasiyalı interfeys@GET, @POST, @Path, @Query, @Body, @Header
  • Converter factory — JSON ↔ obyekt çevrilməsi (Gson, Moshi, kotlinx.serialization)
  • Call adapter — cavabın forması: suspend funksiyalar üçün daxili dəstək, Response<T> ilə status koduna çıxış

Interceptor-lər OkHttp-nin ən güclü mexanizmidir — hər sorğu/cavab zəncirdən keçir:

  • Application interceptor — bir dəfə çağırılır, cache/redirect-dən xəbərsiz: auth header, logging üçün.
  • Network interceptor — real şəbəkə çağırışında: cache davranışını, real gedən sorğunu görür.
  • Authenticator — 401 gələndə çağırılır: token refresh-in düzgün yeri.
kotlin
interface AccountApi {
    @GET("accounts/{id}/balance")
    suspend fun getBalance(@Path("id") accountId: String): BalanceDto

    @POST("transfers")
    suspend fun createTransfer(@Body request: TransferRequest): Response<TransferDto>
}

val client = OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .addInterceptor { chain ->                       // application interceptor
        val request = chain.request().newBuilder()
            .header("Authorization", "Bearer ${tokenStore.access()}")
            .build()
        chain.proceed(request)
    }
    .authenticator { _, response ->                  // 401 → token refresh
        val newToken = tokenStore.refreshBlocking() ?: return@authenticator null
        response.request.newBuilder()
            .header("Authorization", "Bearer $newToken")
            .build()
    }
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.bank.example/v2/")
    .client(client)
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .build()

Bank API üçün tipik Retrofit qurulması

Error handling müsahibə sualı: suspend Retrofit metodu 4xx/5xx-də HttpException, şəbəkə problemində IOException atır. Peşəkar yanaşma: repository-də bunları tutub domain nəticəsinə çevir — sealed interface ApiResult { Success; HttpError(code, errorBody); NetworkError }. Error body-ni parse etməyi unutma: bank API-ləri imtina səbəbini (limit aşımı, kart bloklu) məhz orada qaytarır. baseUrl / ilə bitməlidir — bitməsə IllegalArgumentException; relative path isə / ilə başlamamalıdır.

🛠 Tapşırıq

Pulsuz test API-si üzərində (məs. https://httpbin.org) Retrofit qur:

  • Auth header əlavə edən bir interceptor yaz və logging interceptor ilə göndərilən sorğunu gör.
  • httpbin.org/status/500httpbin.org/status/404 çağır — HttpException-ı tut; sonra internet olmadan çağır — IOException-ı tut.
  • Hər ikisini sealed interface ApiResult-a çevirən repository funksiyası yaz.

Bitdi sayılır: ViewModel-də heç bir try/catch qalmayıbsa.

📚 Mənbələr və sənədlər