Ktor: що це, особливості асинхронного HTTP-клієнта

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

Ktor — це асинхронний HTTP-клієнт для Kotlin, розроблений компанією JetBrains як частина однойменного фреймворку для серверної та клієнтської розробки. Ktor побудований на корутинах Kotlin і підтримує мультиплатформенність. За даними JetBrains, 2025, Ktor забезпечує нативну інтеграцію з Kotlin-екосистемою без рефлексії та додаткових залежностей.

Головне

  • Ktor — асинхронний HTTP-клієнт на Kotlin з мультиплатформенною підтримкою
  • Корутини — основа виконання запитів без колбеків та реактивних потоків
  • Плагіни — модульна система розширення для серіалізації, логування та авторизації
  • Мультиплатформенність — один код для Android, iOS, Desktop та Server
  • Kotlinx Serialization — нативна серіалізація без рефлексії через @Serializable

Що таке Ktor?

Ktor — це фреймворк для побудови асинхронних серверних та клієнтських додатків на Kotlin, створений компанією JetBrains. Ktor Client — клієнтська частина фреймворку, що надає HTTP-клієнт з повною підтримкою корутин Kotlin, мультиплатформенності (JVM, Native, JS) та модульної архітектури на плагінах.

Ktor з'явився у 2018 році як альтернатива Retrofit та OkHttp для Kotlin-first проектів. На відміну від Retrofit, який портував Java-підхід з анотаціями, Ktor Client використовує Kotlin DSL для конфігурації запитів — без анотацій та рефлексії. Це робить код більш читабельним та типобезпечним для Kotlin-розробників.

За даними опитування Kotlin Multiplatform 2024, Ktor Client використовується в 35% проектів Kotlin Multiplatform Mobile (KMM), що робить його другим за популярністю HTTP-клієнтом після OkHttp у Kotlin-спільноті. Ktor надають перевагу в проектах, де важлива мультиплатформенність та нативна інтеграція з Kotlin-екосистемою.

Як працює Ktor Client

Архітектура Ktor Client базується на конвеєрі (pipeline) з плагінів. Кожен запит проходить через послідовність встановлених плагінів, які можуть модифікувати запит, відповідь або виконувати побічні дії — логування, стиснення, серіалізацію, аутентифікацію.

При створенні HTTP-клієнта через HttpClient { } DSL-блоком ви вказуєте двигун (OkHttp, Android, CIO, Darwin) та встановлюєте плагіни. Кожен двигун реалізує низькорівневе відправлення запиту для конкретної платформи: на Android використовується OkHttp-двигун, на iOS — Darwin (URLSession), на Desktop — CIO (Coroutine I/O). HttpClient автоматично вибирає оптимальний двигун для поточної платформи.

Запит у Ktor Client виконується через suspend-функцію, що означає повну інтеграцію з корутинами. Жодних Callback, RxJava або LiveData — лише послідовний код з suspend, який працює асинхронно без блокування потоку.

Конвеєр обробки запиту

Конвеєр Ktor складається з фаз: спочатку запит проходить через встановлені плагіни (наприклад, ContentNegotiation для JSON, Logging для логів), потім двигун виконує HTTP-запит, і відповідь знову проходить через плагіни для десеріалізації. Кожен плагін — це suspend-функція, що виконується в корутині конвеєра.

Важлива перевага конвеєра Ktor — можливість умовної обробки. Плагін може перевірити URL або заголовки запиту та пропустити обробку, якщо умова не виконана. Наприклад, ContentEncoding з gzip застосовується лише до відповідей, що містять заголовок Content-Encoding: gzip, а Auth спрацьовує лише для захищених ендпоінтів, не зачіпаючи публічні API.

Такий pipeline-підхід дозволяє комбінувати плагіни гнучко: ви можете встановити ContentNegotiation з JSON, додати Auth з Bearer-токеном, включити стиснення ContentEncoding та HttpTimeout — і всі вони будуть працювати спільно в правильному порядку. Порядок встановлення плагінів має значення: перший встановлений буде обробляти запит раніше за інших.

Плагіни Ktor Client

Плагіни — це модульна система розширення Ktor, що замінює анотації Retrofit та перехоплювачі OkHttp. Кожен плагін вирішує конкретну задачу та встановлюється через функцію install() у блоці HttpClient. Ktor надає вбудовані плагіни, а також дозволяє створювати кастомні.

ПлагінПризначення
ContentNegotiationСеріалізація та десеріалізація JSON, XML через Kotlinx Serialization
LoggingЛогування запитів та відповідей з налаштуванням рівня
AuthАутентифікація: Basic, Bearer, Digest з автоматичним оновленням токена
HttpTimeoutНалаштування таймаутів підключення, читання та запиту
ContentEncodingПрозоре стиснення gzip та deflate
DefaultRequestВстановлення значень за замовчуванням для всіх запитів

Кастомні плагіни

Для специфічних завдань створюється кастомний плагін через createClientPlugin. Плагін може перехоплювати запит (onRequest), відповідь (onResponse) або обробляти помилки (onError). Це повністю замінює Interceptor з OkHttp, але з типізованим Kotlin-API та підтримкою suspend-функцій.

Кастомні плагіни зручні для додавання метрик, автоматичної ретрай-логіки, трейсингу запитів або A/B-тестування ендпоінтів. На відміну від перехоплювачів OkHttp, Ktor-плагіни написані на Kotlin та працюють в контексті корутини, що спрощує обробку помилок та таймаутів.

Для налагодження запитів використовується плагін Logging з рівнем ALL, HEADERS або BODY. Logging виводить метод, URL, статус, заголовки та тіло запиту та відповіді. На відміну від HttpLoggingInterceptor з OkHttp, Ktor Logging працює асинхронно та може бути налаштований на фільтрацію за рівнем логу (ERROR, WARN, INFO, DEBUG) без зупинки додатка для зміни конфігурації.

Приклади коду Ktor Client на Kotlin

Розглянемо базовий GET-запит через Ktor Client. Створюється HttpClient з встановленим плагіном ContentNegotiation для JSON. Запит виконується через suspend-функцію get(), результат автоматично десеріалізується в data class.

kotlin
data class User(
    val login: String,
    val id: Int,
    val avatarUrl: String
)

val client = HttpClient {
    install(ContentNegotiation) {
        json(Json {
            ignoreUnknownKeys = true
        })
    }
}

suspend fun getUser(): User {
    return client.get("https://api.github.com/users/octocat").body()
}

Для POST-запиту з тілом використовується функція post() з contentType() та body(). Ktor автоматично серіалізує об'єкт в JSON через встановлений ContentNegotiation. DSL-стиль робить код послідовним та читабельним.

kotlin
data class CreateRepo(
    val name: String,
    val description: String,
    val private: Boolean
)

suspend fun createRepo(): Unit {
    val repo = CreateRepo(
        name = "my-project",
        description = "Sample project",
        private = false
    )
    client.post("https://api.github.com/user/repos") {
        contentType(ContentType.Application.Json)
        setBody(repo)
    }
}

Налаштування таймаутів та заголовків

HttpTimeout та DefaultRequest — два ключових плагіни для конфігурації. HttpTimeout встановлює ліміти часу, а DefaultRequest задає заголовки та параметри URL для всіх запитів, позбавляючи від дублювання коду в кожному виклику.

kotlin
val client = HttpClient {
    install(HttpTimeout) {
        connectTimeoutMillis = 15000
        requestTimeoutMillis = 30000
    }
    install(DefaultRequest) {
        url("https://api.github.com/")
        header("Accept", "application/json")
    }
}

Мультиплатформенна підтримка Ktor

Мультиплатформенність — головна перевага Ktor перед OkHttp та Retrofit. Ktor Client працює на JVM (Android, Server), Native (iOS, macOS, Windows, Linux) та JS (Browser). Один і той самий код HTTP-клієнта виконується на всіх платформах без змін, що особливо цінно для Kotlin Multiplatform проектів.

Для кожної платформи Ktor використовує свій двигун (engine). На Android за замовчуванням застосовується OkHttp-двигун, що дає повну сумісність з OkHttp-екосистемою. На iOS використовується DarwinEngine, заснований на URLSession. Для Server — CIOEngine (Coroutine I/O). Двигун можна вказати явно: HttpClient(OkHttp) { } або HttpClient(Darwin) { }.

При виборі двигуна враховуйте його можливості: OkHttp-двигун підтримує HTTP/2 та пул з'єднань, DarwinEngine — нативну інтеграцію з iOS-мережею та фонові сесії URLSession, CIOEngine — чисту корутинну реалізацію без зовнішніх залежностей. Для Web-таргетів використовується JsEngine або BrowserEngine, що працює через fetch API.

Завдяки єдиному API на всіх платформах, код для завантаження даних виглядає однаково на Android, iOS та Desktop. Це скорочує дублювання коду на 60–80% у KMM-проектах порівняно з роздільними реалізаціями на Retrofit (Android) та URLSession (iOS). Плагіни також працюють на всіх платформах без змін.

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

Ігнорування закриття HttpClient — часта помилка в Ktor. HttpClient реалізує Closeable, і його потрібно закривати при завершенні роботи додатка через client.close(). В Android це робиться в onDestroy() Activity або ViewModel.onCleared(). Незакритий клієнт призводить до витоку корутин та потоків двигуна.

Неправильний порядок плагінів може зламати обробку запиту. Наприклад, ContentNegotiation повинен бути встановлений до DefaultRequest, щоб тип контенту застосовувався коректно. Logging рекомендується встановлювати останнім, щоб логувати фінальну версію запиту після всіх модифікацій. Експериментуйте з порядком, якщо плагіни поводяться неочікувано.

Відсутність обробки винятків у suspend-функціях. Ktor викидає винятки IOException при мережевих помилках та ClientRequestException при HTTP-статусах 4xx. Блок try-catch обов'язковий для кожного виклику get(), post() та інших методів. Використовуйте HttpResponseValidator у блоці HttpClient для глобальної обробки помилок без дублювання try-catch у кожному методі.

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

Чим Ktor відрізняється від Retrofit?

Ktor використовує Kotlin DSL та плагіни без анотацій та рефлексії. Retrofit побудований на Java-анотаціях та рефлексії. Ktor підтримує мультиплатформенність, Retrofit — тільки JVM/Android. Ktor нативно працює з корутинами, Retrofit додав suspend через обгортку.

Який двигун Ktor кращий для Android?

Для Android оптимальний OkHttp-двигун — він забезпечує сумісність з OkHttp-екосистемою, пул з'єднань, кешування та HTTP/2. Вибирайте його через HttpClient(OkHttp) { }. Альтернатива — CIOEngine, вбудований в Ktor, але він менш стабільний на Android.

Чи підтримує Ktor HTTP/2?

Так, Ktor підтримує HTTP/2 через відповідний двигун. OkHttp-двигун успадковує підтримку HTTP/2 від OkHttp. DarwinEngine на iOS підтримує HTTP/2 через URLSession. CIOEngine підтримує HTTP/2 на серверній стороні. Вибір двигуна визначає рівень підтримки протоколу.

Як налаштувати авторизацію в Ktor Client?

Використовуйте плагін Auth з встановленням bearer { }. Плагін автоматично додає заголовок Authorization до кожного запиту та може оновлювати токен при відповіді 401 через refreshTokens. Приклад: install(Auth) { bearer { loadTokens { BearerTokens(token, refreshToken) } } }.

Чи можна використовувати Ktor Client на iOS?

Так, Ktor Client повноцінно працює на iOS через DarwinEngine, що використовує URLSession. Всі плагіни, серіалізація та корутини працюють на iOS так само, як на Android. Це робить Ktor основним HTTP-клієнтом для Kotlin Multiplatform Mobile (KMM) проектів.

Підсумки

  • Ktor — асинхронний HTTP-клієнт від JetBrains з мультиплатформенною підтримкою
  • Kotlin DSL замінює анотації — конфігурація через програмні блоки без рефлексії
  • Плагіни ContentNegotiation, Auth, Logging та HttpTimeout модульно розширюють функціональність
  • Корутини — основа виконання: всі методи suspend без колбеків та реактивних потоків
  • Мультиплатформенність — один код для Android, iOS, Desktop, Server та JS
  • Двигуни OkHttp, Darwin, CIO адаптують Ktor під конкретну платформу
  • HttpResponseValidator централізує обробку HTTP-помилок без дублювання try-catch

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

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

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

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