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

Този тръбопроводен подход позволява гъвкаво комбиниране на плъгини: можете да инсталирате 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също