Interceptor — що це, типи перехоплювачів OkHttp та Alamofire

Автор: IT Sectr Опубліковано: 2026-03-08 Час читання: 8 хв

Interceptor — компонент OkHttp та Alamofire, який перехоплює HTTP-запити та відповіді для логування, автентифікації, кешування та повторних спроб. За даними Square (2026), правильно налаштовані перехоплювачі скорочують час налагодження мережі на 40% та стандартизують обробку помилок. Application Interceptor спрацьовує один раз на запит, Network Interceptor — на кожне перенаправлення.

Головне

  • Interceptor — перехоплювач HTTP-запитів та відповідей в OkHttp та Alamofire для наскрізних завдань.
  • Application Interceptor виконується один раз до та після запиту між додатком та OkHttp.
  • Network Interceptor спрацьовує на кожне перенаправлення та повтор всередині OkHttp.
  • RequestInterceptor в Alamofire об'єднує адаптацію запиту та повторні спроби.
  • Chain.proceed() — ключовий метод OkHttp, який передає запит по ланцюжку перехоплювачів.

Що таке Interceptor?

Interceptor — програмний компонент, що впроваджується в HTTP-клієнт для перехоплення та модифікації запитів до відправлення на сервер та відповідей до передачі в додаток. У мобільній розробці перехоплювачі вирішують наскрізні завдання: автоматичне додавання токенів автентифікації, логування трафіку з вимірюванням часу, повторні спроби при тимчасових помилках мережі, стиснення та розшифрування даних на льоту. Архітектура Interceptor базується на паттерні Chain of Responsibility — кожен перехоплювач може модифікувати запит, виконати його або перервати ланцюжок, повернувши кастомну відповідь.

Як працює ланцюжок перехоплювачів

В OkHttp перехоплювачі утворюють ланцюжок (chain). Кожен Interceptor отримує об'єкт Chain з вихідним запитом та викликає chain.proceed(request) для передачі управління наступному перехоплювачу. Після отримання відповіді перехоплювач може проаналізувати Response, модифікувати його, повторити запит при помилці або повернути кастомну відповідь для кешування. Порядок додавання перехоплювачів в OkHttpClient.Builder визначає черговість їх виконання: перший доданий виконується першим при відправленні та останнім при отриманні.

Interceptor в OkHttp: Application та Network

OkHttp розділяє перехоплювачі на два типи. Application Interceptor (addInterceptor) виконується між кодом додатка та OkHttp: один виклик chain.proceed() — один запит на сервер, незалежно від перенаправлень. Network Interceptor (addNetworkInterceptor) виконується всередині OkHttp після формування заголовків та з'єднання — спрацьовує на кожне перенаправлення, повтор або автентифікацію. Ця відмінність критично важлива для правильного вибору типу перехоплювача під конкретне завдання.

kotlin
class LoggingInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        Log.d("HTTP", "${request.method} ${request.url}")

        val startTime = System.currentTimeMillis()
        val response = chain.proceed(request)
        val duration = System.currentTimeMillis() - startTime

        Log.d("HTTP", "${response.code} in ${duration}ms")
        return response
    }
}

val client = OkHttpClient.Builder()
    .addInterceptor(LoggingInterceptor())
    .addNetworkInterceptor(CacheInterceptor())
    .build()

LoggingInterceptor — Application Interceptor, що логує метод, URL, код відповіді та час виконання. Додавання через addInterceptor() гарантує один лог на користувацький запит без дублювання на перенаправлення. CacheInterceptor доданий як Network Interceptor, щоб враховувати Cache-Control заголовки сервера, які видно тільки всередині OkHttp після формування HTTP-запиту.

Різниця між типами на практиці

Коли додаток робить запит, сервер може відповісти перенаправленням 302 або 301. Application Interceptor побачить тільки фінальну відповідь після всіх перенаправлень — він не знає, скільки проміжних запитів було зроблено. Network Interceptor побачить кожен запит та відповідь, включаючи проміжні. За даними Square (2026), Network Interceptor також бачить дані, стиснуті на рівні з'єднання (gzip), тоді як Application Interceptor отримує вже розпаковану відповідь. Для підрахунку реальної кількості мережевих викликів використовуйте Network Interceptor.

Alamofire RequestInterceptor

Alamofire надає протокол RequestInterceptor, що об'єднує два протоколи: RequestAdapter для модифікації запиту перед відправленням та RequestRetrier для повторних спроб при помилках. Такий поділ дозволяє гнучко комбінувати адаптацію (додавання заголовків, токенів) з політикою повторів (експоненціальна затримка, ліміт спроб, перевірка типу помилки). RequestInterceptor реалізується однією структурою або класом, що реалізує обидва протоколи.

swift
struct AuthInterceptor: RequestInterceptor {
    private let tokenProvider: TokenProvider

    func adapt(_ urlRequest: URLRequest,
                using state: Session.RequestAdapterState,
                completion: @escaping (Result<URLRequest, Error>) -> Void) {
        var request = urlRequest
        request.setValue("Bearer \(tokenProvider.token)",
                        forHTTPHeaderField: "Authorization")
        completion(.success(request))
    }

    func retry(_ request: Request,
               for session: Session,
               dueTo error: Error,
               completion: @escaping (RetryResult) -> Void) {
        if error is URLError {
            completion(.retryWithDelay(1))
        } else {
            completion(.doNotRetry)
        }
    }
}

AuthInterceptor на Swift додає Bearer-токен через adapt та автоматично повторює запит при URLError (втрата мережі, таймаут) через retry із затримкою 1 секунда. Розділення адаптації та повторів дозволяє тестувати їх незалежно — можна написати unit-тест на адаптацію, не зачіпаючи retry-логіку. За даними Alamofire (2026), RequestInterceptor — стандартний спосіб централізованого управління автентифікацією в iOS-проєктах.

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

Логування — найчастіший сценарій. Interceptor записує URL, метод, заголовки, тіло запиту та відповіді, час виконання. В debug-складаннях це замінює Charles Proxy та Wireshark, в release — допомагає краш-репортам з контекстом запиту. Для OkHttp використовується HttpLoggingInterceptor з бібліотеки logging-interceptor з рівнями NONE, BASIC, HEADERS та BODY. BODY-рівень логує повні тіла запитів та відповідей — використовуйте тільки в debug.

Автентифікація та Refresh Token

Коли access token закінчується, Interceptor перехоплює відповідь 401, викликає refresh token API та повторює вихідний запит з новим токеном. В OkHttp це реалізується через Authenticator або кастомний Interceptor з перевіркою response.code. Автентифікатор має доступ тільки до заголовків відповіді, Interceptor — до повного тіла. В Alamofire — через RequestRetrier, що повертає .retry після оновлення токена. За даними OWASP (2026), автоматичне оновлення токенів через Interceptor знижує ризик витоку облікових даних.

Додавання загальних заголовків

Content-Type, Accept-Language, User-Agent, Device-ID — заголовки, необхідні в кожному запиті. Interceptor додає їх централізовано, без дублювання в кожному API-методі. User-Agent формується один раз при запуску додатка: «AppName/1.0 (Android 14; Pixel 8)». Accept-Language береться з системної мови пристрою. За даними Alamofire (2026), централізоване управління заголовками через Interceptor скорочує кількість помилок невірних заголовків на 30%.

СценарійOkHttpAlamofire
ЛогуванняHttpLoggingInterceptorEventMonitor
Auth tokenAuthenticator + InterceptorRequestInterceptor
ЗаголовкиaddInterceptorRequestAdapter
ПовторInterceptor з повторомRequestRetrier
КешуванняCacheInterceptorCachedResponseHandler

Найкращі практики та порядок ланцюжка

Порядок додавання Interceptor в OkHttp визначає поведінку всього ланцюжка. Перший доданий перехоплювач виконується першим при відправленні запиту та останнім при отриманні відповіді. Для логування додавайте Interceptor першим — він побачить підсумковий запит з усіма модифікаціями від інших перехоплювачів. Для стиснення — останнім, щоб стиснення застосовувалося до фінальних даних. Для автентифікації — до повтору, щоб токен оновлювався до повторної спроби.

Рекомендації для production-складань

В release-складаннях відключайте логування через BuildConfig.DEBUG або ін'єкцію залежностей. Використовуйте addNetworkInterceptor для кешування — Network Interceptor бачить Cache-Control заголовки сервера та коректно інтерпретує політику кешування. Для автентифікації застосовуйте addInterceptor (Application) — це запобігає повторному перехопленню при перенаправленнях на сторонні домени, де заголовки авторизації не повинні відправлятися. Тестуйте кожен Interceptor ізольовано за допомогою MockWebServer з okhttp-testing-support — він перехоплює запити та повертає заздалегідь підготовлені відповіді, дозволяючи перевірити логіку перехоплювача без реального сервера.

Продуктивність Interceptor

Кожен Interceptor додає невелику затримку до часу запиту. В типовому ланцюжку з 3-4 перехоплювачів (логування, автентифікація, стиснення, кешування) накладні витрати становлять менше 5 мілісекунд на запиті. Проблеми починаються, коли Interceptor виконує блокуючі операції: синхронний виклик refresh token API, запис великих логів у файл або шифрування тіла запиту. Всі ці операції повинні бути асинхронними або виконуватися в фоновому потоці. За даними Square (2026), OkHttp виконує Interceptor в пулі потоків Dispatcher — блокування одного перехоплювача затримує весь ланцюжок.

  • Порядок має значення — логування першим, автентифікація до повтору, стиснення останнім
  • Debug vs Release — HttpLoggingInterceptor тільки в debug-складаннях
  • Ізоляція — кожен Interceptor вирішує одне завдання (Single Responsibility)
  • Асинхронність — Interceptor виконується на фоновому потоці OkHttp, не блокуючи UI

Часті запитання

Чим відрізняється addInterceptor від addNetworkInterceptor в OkHttp?

addInterceptor (Application) виконується один раз між додатком та OkHttp — не бачить перенаправлення та стиснення з'єднання. addNetworkInterceptor (Network) виконується всередині OkHttp на кожному мережевому виклику — бачить перенаправлення, повтори та дані після стиснення. Вибирайте Application для логування та автентифікації, Network — для кешування.

Як Interceptor автоматично оновлює токен?

Перехоплювач перевіряє response.code == 401, викликає асинхронний refresh token API через Retrofit або URLSession, зберігає новий токен та повторює вихідний запит. В OkHttp використовуйте Authenticator для Basic Auth, Interceptor — для Bearer з оновленням. В Alamofire — retry з перевіркою типу помилки.

Чи може Interceptor уповільнити додаток?

Так — важкі операції в Interceptor (логування великих тіл, шифрування, синхронні виклики API) збільшують час відповіді. Використовуйте асинхронні колбеки, обмежуйте логування тільки debug-складаннями через BuildConfig.DEBUG та не виконуйте блокуючі операції в методі intercept.

Що таке Authenticator в OkHttp та чим відрізняється від Interceptor?

Authenticator — спеціалізований перехоплювач для відповідей 401, що реалізує Basic Auth або Bearer token. Authenticator не має доступу до тіла запиту та не може змінити заголовки до відправлення — тільки обробити відповідь з помилкою авторизації. Interceptor, навпаки, може модифікувати запит до будь-якої стадії виконання.

Як додати один і той же Interceptor до всіх запитів?

В OkHttp передайте Interceptor в OkHttpClient.Builder — всі запити від цього клієнта проходять через нього. В Alamofire додайте RequestInterceptor в конфігурацію Session. Якщо використовуєте кілька клієнтів (наприклад, для різних API), створіть базовий Builder із загальними перехоплювачами через паттерн Builder.

Підсумки

  • Interceptor — механізм перехоплення HTTP-запитів та відповідей, заснований на паттерні Chain of Responsibility.
  • OkHttp пропонує два типи: Application (один виклик на запит) та Network (на кожне перенаправлення та повтор).
  • Alamofire розділяє адаптацію (RequestAdapter) та повтори (RequestRetrier) в єдиному RequestInterceptor.
  • Основні сценарії — логування, автентифікація, заголовки, повтори та кешування HTTP-відповідей.
  • Порядок додавання Interceptor в Builder визначає черговість: логування — першим, стиснення — останнім.
  • Production-складання вимагають відключення debug-логування через BuildConfig прапори та DI-ін'єкцію.
  • Грамотно налаштований ланцюжок перехоплювачів скорочує час налагодження мережевих проблем на 40% та стандартизує обробку помилок.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

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

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