Retrofit — је типизовани HTTP клијент за Android и Kotlin, развијен од стране компаније Square. Библиотека омогућава претварање REST API-ја у интерфејс на Java или Kotlin-у помоћу анотација. Према подацима Square, 2025, Retrofit се користи у хиљадама апликација као стандардни алат за рад са HTTP захтевима.
Главно
Retrofit — је библиотека за типизовану интеракцију са REST API-јем на Android платформи, развијена од стране компаније Square. Пружа декларативни начин описивања HTTP захтева преко Java или Kotlin интерфејса са анотацијама, потпуно ослобађајући програмера од ручног парсирања JSON-а и управљања HTTP везама.
Библиотека се појавила 2013. године као алтернатива гломазним решењима попут AsyncTask-а и HttpURLConnection-а. До 2025. године Retrofit остаје де факто стандард за мрежну комуникацију у Android апликацијама захваљујући једноставности и типској безбедности. Према истраживању JetBrains Developer Ecosystem 2024, Retrofit користи више од 65% Android програмера у комерцијалним пројектима.
Кључна разлика Retrofit-а од аналога — декларативни приступ: програмер описује шта да ради (који endpoint да позове, које параметре да проследи), а не како да ради (како да отвори везу, како да чита InputStream, како да парсира JSON). Ово смањује количину boilerplate кода за 60–70% у поређењу са ручним коришћењем HttpURLConnection-а.
Принцип рада Retrofit-а се заснива на динамичким проксијима Java. Када програмер позове метод интерфејса означеног анотацијама, Retrofit кроз механизам Proxy.newProxyInstance пресреће позив и претвара га у HTTP захтев. Цео процес се одвија у runtime-у без генерисања кода у фази компилације.
Приликом креирања инстанце Retrofit.Builder-а наводи се базни URL и фабрика конвертора. Builder конфигурише OkHttpClient — поставља тајмауте, интерцепторе, pool веза и кеш. Метод create(Class) генерише имплементацију интерфејса, враћајући прокси објекат који се може позивати као обична класа.
Ланац извршења захтева изгледа овако: анотације издвајају HTTP метод, параметри се убацују у URL или тело захтева, конвертор серијализује тело, OkHttp извршава захтев, конвертор десеријализује одговор, резултат се враћа у наведеном типу. Свака фаза је изолована и може се заменити прилагођеном имплементацијом, на пример замена OkHttpClient-а са MockWebServer-ом за тестирање или промена конвертора при промени API-ја.
Важна карактеристика — Retrofit не подржава директни стриминг података. За стримовање се користи OkHttp ResponseBody као повратни тип метода интерфејса. Retrofit такође не управља аутоматски отказивањем захтева — за отказивање је потребно сачувати референцу на Call и позвати cancel(). У Kotlin-у са suspend функцијама, отказивање захтева се дешава аутоматски при отказивању родитељске корутине.
Call<T> — је објекат који представља један HTTP захтев. Након извршења (execute или enqueue), Call се не може поново користити — за поновни захтев потребно је креирати нови Call позивом метода интерфејса. Ово штити од случајног слања истог захтева два пута, што би могло довести до дуплирања операција на серверу.
У Kotlin-у уместо Call-а користе се suspend функције које аутоматски управљају животним циклусом захтева. Retrofit сам пребацује извршење на Dispatchers.IO и враћа резултат у корутину. Ово скраћује код за 30–40% у поређењу са верзијом на Call и Callback.
Анотације — су основни механизам конфигурације HTTP захтева у Retrofit-у. Свака анотација одговара стандардном HTTP методу и прихвата релативну путању до endpoint-а. Retrofit подржава GET, POST, PUT, DELETE, PATCH, HEAD и OPTIONS.
| Анотација | HTTP метод | Намена |
|---|---|---|
| @GET | GET | Преузимање података са сервера |
| @POST | POST | Креирање новог ресурса |
| @PUT | PUT | Потпуно ажурирање ресурса |
| @DELETE | DELETE | Брисање ресурса |
| @PATCH | PATCH | Делимично ажурирање ресурса |
@Path замењује вредност у сегменту URL-а: @Path(id) Int id замењује {id} у путањи. @Query додаје query параметар: @Query(page) Int page претвара се у ?page=5. @Body прослеђује објекат у телу захтева са аутоматском серијализацијом кроз изабрани конвертор. @Header и @Headers управљају HTTP заглављима — статичким или динамичким.
Комбинујући ове анотације, може се описати било који REST endpoint. На пример, за endpoint POST /api/users/{id}/posts?limit=10 биће потребни @POST, @Path за id, @Query за limit и @Body за прослеђени објекат. Retrofit ће аутоматски саставити исправан HTTP захтев. Додатно се подржавају @Url (динамички URL), @Field (form-encoded тело), @Part и @PartMap за multipart захтеве са датотекама.
Размотримо практични пример — интерфејс за GitHub API. Креира се Kotlin интерфејс са методом за добијање листе репозиторијума. Data class Repo описује структуру JSON одговора.
data class Repo(
val name: String,
val description: String?,
val stargazersCount: Int,
val forksCount: Int
)
interface GitHubApi {
@GET("users/{user}/repos")
suspend fun getRepos(
@Path("user") user: String,
@Query("sort") sort: String = "updated"
): List<Repo>
}
Након описа интерфејса креира се инстанца Retrofit-а кроз Builder. Базни URL, конвертор и OkHttpClient се подешавају једном и поново користе кроз dependency injection.
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.client(OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.build())
.build()
val api = retrofit.create(GitHubApi::class.java)
За флексибилну обраду HTTP статуса користите омот Response<T>. Омогућава приступ коду одговора, заглављима и телу, без бацања изузетка при грешкама 4xx и 5xx. Ово омогућава обраду 404 и 500 без try-catch.
interface GitHubApi {
@GET("users/{user}/repos")
suspend fun getRepos(
@Path("user") user: String
): Response<List<Repo>>
}
val response = api.getRepos("octocat")
if (response.isSuccessful) {
println(response.body()?.size)
} else {
Log.e("API", "Greška: ${response.code()}")
}
Конвертори — су компоненте Retrofit-а задужене за претварање објеката у HTTP тело и обрнуто. Retrofit не уграђује серијализацију у језгро — уместо тога користи се модуларни приступ кроз Converter.Factory, омогућавајући прикључивање било које библиотеке за серијализацију.
Најпопуларнији конвертор — GsonConverterFactory од Google-а на бази Gson библиотеке. Погодан је за већину пројеката, подржава прилагођене TypeAdapter и JsonDeserializer. Међутим, Gson користи рефлексију и не узима у обзир null safety Kotlin-а, што може довести до NPE при неочекиваним null пољима.
Алтернатива — MoshiConverterFactory од Square-а: строжи према типовима, са бољом подршком за Kotlin (null safety, default values) и без рефлексије. За пројекте на чистом Kotlin-у оптималан је Kotlinx Serialization Converter, који ради на @Serializable анотацијама у фази компилације. Не користи рефлексију, подржава sealed class, default values и вишеплатформност.
Избор конвертора утиче на перформансе и безбедност типова. Gson без прилагођене конфигурације може десеријализовати null у non-null поље Kotlin-а, изазивајући NPE при приступу. Moshi решава овај проблем кроз анотацију @Json(name) и failOnUnknown. Kotlinx Serialization је најсигурнији — генерише код у фази компилације, потпуно искључујући runtime грешке типова.
Недостатак обраде HTTP грешака у suspend функцијама — најчешћи проблем. Ако сервер врати 4xx или 5xx, Retrofit баца HttpException. Без try-catch апликација ће се нагло прекинути. Коришћење Response<T> као повратног типа решава овај проблем, омогућавајући проверу isSuccessful пре приступа body-ју.
Неправилно подешавање кеширања доводи до прекомерног саобраћаја. Retrofit не кешира одговоре сам — овај задатак решава OkHttpClient кроз Cache. Без кеша, сваки захтев се извршава у потпуности, чак и када се подаци нису променили. Додавање Cache-а величине 10 MB у OkHttpClient смањује саобраћај за 40–60% при поновљеним захтевима истих информација.
Креирање Retrofit-а за сваки захтев — честа грешка почетника. Retrofit.Builder је ресурсно захтевна операција која укључује генерисање прокси класа у runtime-у. Исправна пракса — креирати једну инстанцу Retrofit-а и поново је користити кроз DI оквире. Hilt, Koin или Dagger обезбеђују синглтон инстанцу Retrofit-а за целу апликацију, што штеди меморију и убрзава захтеве.
Игнорисање Interceptor-а за ауторизацију — четврти проблем. Уместо ручног додавања заглавља Authorization у сваки позив, подесите глобални Interceptor у OkHttpClient-у. Interceptor пресреће сваки захтев, додаје Bearer токен, а Authenticator обрађује одговор 401, обнављајући токен и понављајући захтев аутоматски. Ово централизује логику аутентификације.
Често постављана питања
Retrofit — је надградња над OkHttp-ом која пружа декларативни API кроз анотације. OkHttp — нискоризирани HTTP клијент који ради директно са Request и Response. Retrofit поједностављује типизацију, серијализацију и обраду одговора, користећи OkHttp као транспорт.
За Java пројекте — GsonConverterFactory. За Kotlin са Moshi-јем — MoshiConverterFactory (безбеднији по типовима). Оптимални избор за чисти Kotlin — Kotlinx Serialization Converter. Ради без рефлексије, подржава sealed class и default values.
Да, од верзије 2.6.0 Retrofit подржава suspend функције. Декларишите метод као suspend, и Retrofit ће извршити захтев на Dispatchers.IO, враћајући резултат у корутину. Не треба користити Call и enqueue — код постаје секвенцијалан.
Ауторизација се додаје кроз Interceptor OkHttp-а. У intercept() додајте заглавље Authorization. За динамички токен користите Authenticator OkHttp-а — пресреће одговор 401 и аутоматски обнавља токен, понављајући захтев са новим заглављем.
Не може — Retrofit увек користи OkHttp као транспортни слој. OkHttpClient се прослеђује кроз Builder.client() и управља тајмаутима, интерцепторима, кеширањем и pool-ом веза. Без OkHttp-а Retrofit не може извршити ниједан захтев.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође