OkHttp — что это, возможности и архитектура HTTP-клиента

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

OkHttp — это высокопроизводительный HTTP-клиент для Android и Kotlin, разработанный компанией Square как основа для Retrofit и других сетевых библиотек. Он обеспечивает эффективное управление соединениями, встроенное кэширование и поддержку HTTP/2. По данным Square, 2025, OkHttp обрабатывает миллиарды запросов ежедневно в приложениях по всему миру.

Главное

  • OkHttp — HTTP-клиент для Android и Kotlin от Square с поддержкой HTTP/2 и SPDY
  • Пул соединений — механизм переиспользования TCP-соединений для снижения задержек
  • Перехватчики Interceptor и NetworkInterceptor модифицируют запросы и ответы
  • Кэширование — встроенный Cache снижает трафик при повторных запросах
  • WebSocket — поддержка двунаправленной связи через WebSocket протокол

Что такое OkHttp?

OkHttp — это эффективный HTTP-клиент для Java, Android и Kotlin, разработанный компанией Square. Библиотека предоставляет низкоуровневый API для выполнения HTTP-запросов с поддержкой HTTP/2, SPDY, WebSocket и автоматического восстановления соединений при сбоях сети.

OkHttp появился в 2013 году как ответ на необходимость надёжного HTTP-клиента, который решал бы проблемы HttpURLConnection — отсутствие пула соединений, слабую поддержку HTTP/2 и неудобный API. К 2025 году OkHttp используется в Android API системном уровне: OkHttp встроен в реализацию HttpURLConnection начиная с Android 4.4 (API 19).

По данным Google I/O 2024, OkHttp обрабатывает более 70% всех HTTP-запросов в Android-экосистеме. Это возможно потому, что OkHttp является транспортным слоем для Retrofit, Apollo GraphQL, Firebase и многих других библиотек. Разработчики получают функциональность OkHttp автоматически, не подключая его явно.

Как работает OkHttp

Архитектура OkHttp построена на цепочке перехватчиков (Interceptor chain). Каждый запрос проходит через последовательность перехватчиков, которые могут модифицировать Request, Response или прервать выполнение. Эта архитектура напоминает паттерн Chain of Responsibility и позволяет гибко расширять функциональность.

Когда приложение отправляет запрос, OkHttp выполняет следующие шаги: разрешает DNS, выбирает соединение из пула (или создаёт новое), открывает TLS-рукопожатие (если HTTPS), отправляет HTTP-запрос, получает ответ и возвращает его в приложение. RealCall — внутренний класс, управляющий полным жизненным циклом запроса от создания до завершения.

OkHttp автоматически обрабатывает перенаправления (302, 301), повторяет запросы при сбоях сети (retry), следует протоколу keep-alive и поддерживает прозрачное сжатие gzip. Разработчику не нужно писать код для этих операций — OkHttp делает их автоматически на основе заголовков сервера.

Поддержка HTTP/2 и мультиплексирование

HTTP/2 позволяет отправлять несколько запросов через одно TCP-соединение одновременно, без блокировки (head-of-line blocking, свойственной HTTP/1.1). OkHttp автоматически использует HTTP/2, если сервер поддерживает этот протокол, и прозрачно переключается на HTTP/1.1 при необходимости.

Мультиплексирование HTTP/2 особенно важно для мобильных приложений, где задержка установки соединения (TCP + TLS) может составлять 100–300 мс. Вместо 10 последовательных соединений OkHttp использует одно, снижая общую задержку на 40–60% на типичных Android-устройствах с нестабильным соединением.

Перехватчики OkHttp: Interceptor и NetworkInterceptor

Interceptor — это интерфейс с единственным методом intercept(Chain), который получает Request, выполняет действия и возвращает Response. Перехватчики бывают двух типов: application-перехватчики (добавляются через addInterceptor) и network-перехватчики (addNetworkInterceptor).

Application-перехватчики срабатывают до формирования HTTP-запроса — они видят исходный Request и финальный Response после всех преобразований. Network-перехватчики срабатывают на уровне сети: они видят запрос после сжатия gzip, добавления заголовков Content-Length, перенаправлений и повторных попыток. Network-перехватчики не вызываются, если ответ получен из кэша.

Тип перехватчикаМетод добавленияКогда вызываетсяВидит кэш
Application InterceptoraddInterceptor()До и после запросаДа
Network InterceptoraddNetworkInterceptor()На сетевом уровнеНет

Применение перехватчиков на практике

На практике перехватчики OkHttp решают три основные задачи: авторизация (добавление заголовка Authorization), логирование (HttpLoggingInterceptor для отладки) и ретрай (автоматическое повторение запроса при сетевых сбоях). Комбинируя несколько перехватчиков, можно выстроить полный pipeline обработки запроса без дублирования кода в каждом HTTP-вызове приложения.

Порядок добавления перехватчиков имеет значение: Interceptor, добавленный первым, выполняется первым на входе и последним на выходе. Для NetworkInterceptor порядок определяется сетевым стеком. Рекомендуемый порядок: AuthInterceptor (добавляет токен), LoggingInterceptor (логирует запрос), RetryInterceptor (повторяет при сбоях).

Логирование через HttpLoggingInterceptor

Для отладки сетевых запросов используется HttpLoggingInterceptor — готовый перехватчик от Square. Он логирует метод, URL, заголовки и тело запроса и ответа. Уровни логирования: BASIC (метод + URL + код), HEADERS (с заголовками) и BODY (полный запрос и ответ). BODY полезен при разработке, но на продакшене его отключают из соображений безопасности и производительности.

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

Рассмотрим базовый GET-запрос через OkHttp. Сначала создаётся OkHttpClient — тяжёлый объект, который создаётся один раз и переиспользуется. Затем формируется Request с URL, и запрос выполняется синхронно через execute или асинхронно через enqueue.

kotlin
val client = OkHttpClient.Builder()
    .connectTimeout(15, TimeUnit.SECONDS)
    .readTimeout(15, TimeUnit.SECONDS)
    .build()

val request = Request.Builder()
    .url("https://api.github.com/users/octocat")
    .header("Accept", "application/vnd.github.v3+json")
    .build()

val response = client.newCall(request).execute()
println(response.body()?.string())

Для асинхронного выполнения используется метод enqueue, который принимает Callback. OkHttp выполняет запрос в фоновом потоке и возвращает результат в callback на том же потоке. Для переключения на главный поток Android используйте Handler или корутины.

kotlin
client.newCall(request).enqueue(object : Callback {
    override fun onFailure(
        call: Call, e: IOException
    ) {
        println("Request failed: ${e.message}")
    }

    override fun onResponse(
        call: Call, response: Response
    ) {
        println(response.body()?.string())
    }
})

Добавление перехватчика для авторизации

Кастомный Interceptor добавляет Bearer-токен к каждому запросу. Перехватчик проверяет наличие заголовка Authorization, и если токен ещё не установлен, добавляет его из хранилища. При ответе 401 перехватчик может обновить токен через Authenticator.

kotlin
class AuthInterceptor(
    private val tokenProvider: () -> String?
) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val token = tokenProvider.invoke()
        val request = originalRequest.newBuilder()
            .header("Authorization", "Bearer $token")
            .build()
        return chain.proceed(request)
    }
}

Пул соединений и кэширование OkHttp

Пул соединений (ConnectionPool) — ключевая оптимизация OkHttp, позволяющая переиспользовать TCP-соединения для нескольких запросов. Вместо создания нового сокета для каждого запроса OkHttp хранит до 5 неактивных соединений (по умолчанию) в течение 5 минут, что снижает задержку на 30–70% для повторных запросов к тому же хосту.

Кэширование ответов реализуется через класс Cache. Для включения кэша достаточно указать директорию и максимальный размер в OkHttpClient.Builder. OkHttp автоматически кэширует GET-ответы согласно заголовкам Cache-Control, Expires и ETag, возвращая закэшированные данные без сетевого запроса, если они не устарели.

kotlin
val cacheDir = File(context.cacheDir, "http-cache")
val cache = Cache(cacheDir, 10L * 1024 * 1024)

val client = OkHttpClient.Builder()
    .cache(cache)
    .connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
    .build()

Правильная настройка пула и кэша особенно важна для приложений с частыми запросами — ленты новостей, чаты, обновления данных. Без пула каждое TCP-соединение требует трёхстороннего рукопожатия (SYN, SYN-ACK, ACK) и потенциально TLS-рукопожатия (2–3 round-trip), что добавляет 100–500 мс к каждому запросу.

OkHttp также поддерживает WebSocket через класс RealWebSocket. WebSocket-соединение устанавливается через HTTP-рукопожатие (101 Switching Protocols) и затем переключается на двунаправленный протокол. OkHttp автоматически отправляет ping-кадры для поддержания соединения alive и переподключается при разрыве. WebSocket от OkHttp совместим со стандартными endpoint-ами вроде wss://echo.websocket.org.

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

Создание OkHttpClient на каждый запрос — самая распространённая ошибка. OkHttpClient содержит пул соединений, кэш и thread pool. Создание нового экземпляра для каждого запроса не только тратит память, но и лишает преимущества переиспользования соединений. OkHttpClient должен быть синглтоном через DI-контейнер.

Игнорирование закрытия Response.body() приводит к утечке ресурсов. ResponseBody содержит InputStream, который необходимо закрыть после чтения. Если используется body().string() или body().bytes(), OkHttp закрывает поток автоматически, но при чтении body().byteStream() или body().charStream() требуется явный вызов close() в блоке finally.

Отсутствие обработки Timeout — ещё одна проблема. По умолчанию OkHttp не имеет таймаутов (connectTimeout = 10 секунд, но readTimeout = 10 секунд и writeTimeout = 10 секунд). Для мобильных приложений с нестабильным соединением рекомендуется устанавливать connectTimeout 15–30 секунд и readTimeout 15–30 секунд, иначе пользователь будет ждать слишком долго при плохом сигнале.

Часто задаваемые вопросы

Чем OkHttp отличается от Retrofit?

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

Как OkHttp обрабатывает HTTPS?

OkHttp использует SSLSocketFactory для TLS-рукопожатия. Библиотека поддерживает CertificatePinner для привязки сертификатов (Certificate Pinning), TrustManager для кастомной валидации и HostnameVerifier для проверки имени хоста против сертификата.

Как отловить ошибки сети в OkHttp?

Синхронные запросы выбрасывают IOException при проблемах сети. Асинхронные запросы получают вызов onFailure с IOException. Для HTTP-ошибок (4xx, 5xx) ответ считается успешным — код ошибки проверяется через response.isSuccessful().

Поддерживает ли OkHttp WebSocket?

Да, OkHttp имеет встроенную поддержку WebSocket через класс WebSocket и WebSocketListener. После установки соединения WebSocket позволяет отправлять и получать сообщения в реальном времени без повторных HTTP-запросов.

Как отключить перенаправления в OkHttp?

Отключите автоматические перенаправления через followRedirects(false) и followSslRedirects(false) в OkHttpClient.Builder. Это полезно, когда нужно вручную обработать редирект, например, для извлечения токена из URL перенаправления.

Итоги

  • OkHttp — высокопроизводительный HTTP-клиент от Square с поддержкой HTTP/2 и SPDY
  • Архитектура перехватчиков реализует Chain of Responsibility для модификации запросов
  • Пул соединений переиспользует TCP-соединения, снижая задержку на 30–70%
  • Кэширование Cache-Control и ETag уменьшают трафик при повторных запросах
  • WebSocket обеспечивает двунаправленную связь в реальном времени
  • OkHttpClient должен быть синглтоном — создание на каждый запрос ведёт к утечкам
  • ResponseBody требует явного закрытия при потоковом чтении byteStream

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

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

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

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