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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также