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.
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/500vəhttpbin.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
- Retrofit sənədlərirəsmilysine.dev
- OkHttp sənədlərirəsmilysine.dev
- OkHttp Interceptorsrəsmilysine.dev