Retrofit: что это такое, особенности HTTP-клиента Android

Автор: IT Sectr Опубликовано: 2026-03-07 Время чтения: 8 мин

Retrofit — это типизированный HTTP-клиент для Android и Kotlin, разработанный компанией Square. Библиотека позволяет превратить REST API в интерфейс на Java или Kotlin с помощью аннотаций. По данным Square, 2025, Retrofit используется в тысячах приложений как стандартный инструмент для работы с HTTP-запросами.

Главное

  • Retrofit — типизированный HTTP-клиент от Square для Android и Kotlin с декларативным API
  • Аннотации @GET, @POST, @Path, @Query описывают HTTP-запросы без boilerplate-кода
  • Конвертеры Gson, Moshi и Kotlinx Serialization преобразуют JSON в объекты Kotlin
  • OkHttp — обязательный транспортный слой, выполняющий все HTTP-запросы под капотом Retrofit
  • Suspend-функции интегрируют Retrofit с корутинами Kotlin для асинхронных вызовов

Что такое Retrofit?

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

Принцип работы 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

Call<T> — это объект, представляющий один HTTP-запрос. После выполнения (execute или enqueue) Call нельзя переиспользовать — для повторного запроса нужно создать новый Call через вызов метода интерфейса. Это защищает от случайной отправки одного запроса дважды, что могло бы привести к дублированию операций на сервере.

В Kotlin вместо Call используются suspend-функции, которые автоматически управляют жизненным циклом запроса. Retrofit сам переключает выполнение на Dispatchers.IO и возвращает результат в корутину. Это сокращает код на 30–40% по сравнению с версией на Call и Callback.

Аннотации Retrofit для HTTP-методов

Аннотации — это основной механизм конфигурации HTTP-запросов в Retrofit. Каждая аннотация соответствует стандартному HTTP-методу и принимает относительный путь до эндпоинта. Retrofit поддерживает GET, POST, PUT, DELETE, PATCH, HEAD и OPTIONS.

АннотацияHTTP-методНазначение
@GETGETПолучение данных с сервера
@POSTPOSTСоздание нового ресурса
@PUTPUTПолное обновление ресурса
@DELETEDELETEУдаление ресурса
@PATCHPATCHЧастичное обновление ресурса

Аннотации параметров запроса

@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-запросов с файлами.

Примеры кода Retrofit на Kotlin

Рассмотрим практический пример — интерфейс для API GitHub. Создаётся Kotlin-интерфейс с методом получения списка репозиториев. Data class Repo описывает структуру JSON-ответа.

kotlin
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.

kotlin
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)

Обработка ответа с обёрткой Response

Для гибкой обработки HTTP-статусов используйте обёртку Response<T>. Она даёт доступ к коду ответа, заголовкам и телу, не выбрасывая исключение при ошибках 4xx и 5xx. Это позволяет обрабатывать 404 и 500 без try-catch.

kotlin
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

Конвертеры — это компоненты 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-ошибки типов полностью.

Типовые ошибки при работе с Retrofit

Отсутствие обработки 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?

Retrofit — это надстройка над OkHttp, предоставляющая декларативный API через аннотации. OkHttp — низкоуровневый HTTP-клиент, работающий с Request и Response напрямую. Retrofit упрощает типизацию, сериализацию и обработку ответов, используя OkHttp как транспорт.

Какой конвертер для Retrofit выбрать?

Для Java-проектов — GsonConverterFactory. Для Kotlin с Moshi — MoshiConverterFactory (безопаснее по типам). Оптимальный выбор для чистого Kotlin — Kotlinx Serialization Converter. Он работает без рефлексии, поддерживает sealed class и default values.

Поддерживает ли Retrofit корутины?

Да, начиная с версии 2.6.0 Retrofit поддерживает suspend-функции. Объявите метод как suspend, и Retrofit выполнит запрос на Dispatchers.IO, вернув результат в корутину. Не нужно использовать Call и enqueue — код становится последовательным.

Как настроить авторизацию в Retrofit?

Авторизация добавляется через Interceptor OkHttp. В intercept() добавьте заголовок Authorization. Для динамического токена используйте Authenticator OkHttp — он перехватывает ответ 401 и автоматически обновляет токен, повторяя запрос с новым заголовком.

Можно ли использовать Retrofit без OkHttp?

Нельзя — Retrofit всегда использует OkHttp как транспортный слой. OkHttpClient передаётся через Builder.client() и управляет таймаутами, перехватчиками, кэшированием и пулом соединений. Без OkHttp Retrofit не сможет выполнить ни одного запроса.

Итоги

  • Retrofit — типизированный HTTP-клиент от Square для Android и Kotlin с декларативным аннотационным API
  • Аннотации @GET, @POST, @Path, @Query и @Body описывают REST-запросы без boilerplate-кода
  • Динамические прокси Java преобразуют вызовы методов интерфейса в HTTP-запросы в runtime
  • Конвертеры Gson, Moshi и Kotlinx Serialization обеспечивают сериализацию JSON в объекты
  • OkHttp — обязательный транспортный слой с перехватчиками, кэшированием и пулом соединений
  • Suspend-функции интегрируют асинхронные HTTP-вызовы с корутинами Kotlin
  • Response обёртка обрабатывает HTTP-ошибки 4xx и 5xx без необработанных исключений

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также