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 від аналогів — декларативний підхід: розробник описує що робити (який ендпоінт викликати, які параметри передати), а не як робити (як відкрити з'єднання, як прочитати InputStream, як розпарсити JSON). Це знижує кількість boilerplate-коду на 60–70% порівняно з ручним використанням HttpURLConnection.
Принцип роботи Retrofit заснований на динамічних проксі Java. Коли розробник викликає метод інтерфейсу, позначеного анотаціями, Retrofit через механізм Proxy.newProxyInstance перехоплює виклик і перетворює його на HTTP-запит. Весь процес відбувається в runtime без генерації коду на етапі компіляції.
При створенні екземпляра Retrofit.Builder вказується базовий URL та фабрика конвертерів. Builder конфігурує OkHttpClient — задає таймаути, перехоплювачі, пул з'єднань і кеш. Метод 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-методу та приймає відносний шлях до ендпоінту. 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 ендпоінт. Наприклад, для ендпоінта POST /api/users/{id}/posts?limit=10 знадобиться @POST, @Path для id, @Query для limit і @Body для об'єкта, що передається. Retrofit автоматично збере коректний HTTP-запит. Додатково підтримуються @Url (динамічний URL), @Field (form-encoded тіло), @Part і @PartMap для multipart-запитів з файлами.
Розглянемо практичний приклад — інтерфейс для API GitHub. Створюється 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", "Error: ${response.code()}")
}
Конвертери — це компоненти Retrofit, що відповідають за перетворення об'єктів у HTTP-тіло і назад. Retrofit не вбудовує серіалізацію в ядро — натомість використовується modular-підхід через 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 МБ в 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() і керує таймаутами, перехоплювачами, кешуванням і пулом з'єднань. Без OkHttp Retrofit не зможе виконати жодного запиту.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також