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 побудована на ланцюзі перехоплювачів. Кожний запит проходить через послідовність перехоплювачів, які можуть модифікувати запит, відповідь або перервати виконання. Ця архітектура нагадує патерн Chain of Responsibility і дозволяє гнучко розширювати функціонал.

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

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

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

HTTP/2 дозволяє надсилати кілька запитів через одне TCP-з’єднання одночасно, без блокування head-of-line (властивого для 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), який отримує запит, виконує дії та повертає відповідь. Існують два типи перехоплювачів: прикладні (додаються через addInterceptor) та мережеві (addNetworkInterceptor).

Прикладні перехоплювачі спрацьовують до формування HTTP-запиту — вони бачать оригінальний запит та фінальну відповідь після всіх перетворень. Мережеві перехоплювачі спрацьовують на рівні мережі: вони бачать запит після стиснення gzip, додавання заголовка Content-Length, перенаправлень та повторних спроб. Мережеві перехоплювачі не викликаються, якщо відповідь отримано з кешу.

Тип перехоплювачаМетод додаванняКоли викликаєтьсяБачить кеш
Application InterceptoraddInterceptor()До та після запитуТак
Network InterceptoraddNetworkInterceptor()На мережевому рівніНі

Застосування перехоплювачів на практиці

На практиці перехоплювачі OkHttp вирішують три основні завдання: авторизація (додавання заголовка Authorization), логування (HttpLoggingInterceptor для налагодження) та повторна спроба (автоматичне повторення запиту при збоях мережі). Комбінуючи кілька перехоплювачів, можна побудувати повний конвеєр обробки запитів без дублювання коду в кожному 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 виконує запит у фоновому потоці та повертає результат у зворотному виклику на тому ж потоці. Для перемикання на головний потік Android використовуйте Handler або корутини.

kotlin
client.newCall(request).enqueue(object : Callback {
    override fun onFailure(
        call: Call, e: IOException
    ) {
        println("Запит не вдався: ${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 раунди), що додає 100–500 мс до кожного запиту.

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

Типові помилки при роботі з OkHttp

Створення OkHttpClient на кожний запит — найпоширеніша помилка. OkHttpClient містить пул з’єднань, кеш та пул потоків. Створення нового екземпляра для кожного запиту не тільки марнує пам’ять, але й позбавляє переваг повторного використання з’єднань. 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 для прив’язки сертифікатів, 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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