Ktor — е асинхронен HTTP клиент и сървърна рамка за Kotlin, която поддържа мултиплатформена разработка. Библиотеката е изградена върху корутини на Kotlin и работи на JVM, iOS, Android, JS и Native. Според данни от хранилището на Ktor в GitHub, проектът се развива активно от екипа на JetBrains. Ktor предлага модулна архитектура с плъгин система за гъвкаво конфигуриране на HTTP връзки.
Основни точки
Ktor — е рамка за създаване на HTTP клиенти и сървъри на езика Kotlin, разработена от компанията JetBrains. За разлика от традиционните библиотеки, Ktor от самото начало е проектиран за мултиплатформена разработка и работи на всички платформи, поддържани от Kotlin.
Ktor използва подход на междинни обработвачи, вдъхновен от архитектурата на Kodein и Express.js. Всяка заявка преминава през тръбопровод от функции-обработвачи, които могат да модифицират заявката и отговора. Това осигурява гъвкавост, която не е налична в библиотеки с твърда архитектура, базирана на анотации.
Текущата версия Ktor 3.0 включва поддръжка за Kotlin 2.0, K2 компилатора и нов двигател CIO (Coroutine I/O) с подобрена производителност. Библиотеката се разпространява под лиценз Apache 2.0 и е достъпна за търговска употреба без ограничения.
Клиентската част на Ktor е изцяло изградена върху корутини на Kotlin, което осигурява ефективно асинхронно изпълнение на заявки без блокиране на нишки. Сървърната част позволява създаване на HTTP сървъри с маршрутизация, обработка на заявки и WebSocket връзки.
Ktor използва плъгин архитектура: всички допълнителни функции — логване, сериализация, удостоверяване — се свързват чрез плъгини. Това прави библиотеката модулна и позволява свързване само на необходимите компоненти, намалявайки размера на крайното приложение.
Благодарение на единното API на всички платформи, разработчикът не трябва да учи различни HTTP клиенти за iOS и Android. В мултиплатформен проект кодът на мрежовия слой е изцяло споделен, а имплементацията, специфична за платформата, е скрита зад двигателя HttpClient. Това съкращава времето за разработка и намалява броя на грешките, свързани с разликите между платформите.
Ktor предлага набор от функции, които го правят атрактивен избор за съвременни Kotlin проекти, особено мултиплатформени.
Ktor работи на JVM, Android, iOS, macOS, Windows, Linux, JavaScript и Wasm. Същият код на HTTP клиента работи на всички платформи без промени. Това е ключово предимство пред библиотеки, обвързани с OkHttp или URLSession.
Корутините на Kotlin осигуряват естествена асинхронност без обратни извиквания. Всяка заявка е suspend-функция, която може да бъде извикана от всяка корутина. Ktor поддържа стрийминг на отговори чрез Flow, което е удобно за дълги връзки и WebSocket.
Плъгините на Ktor се свързват чрез install блок и се конфигурират отделно. Основни плъгини: ContentNegotiation за сериализация, Logging за логване, Auth за удостоверяване и WebSockets за двупосочна комуникация. Всеки плъгин може да бъде активиран или деактивиран независимо.
Обработката на грешки в Ktor е базирана на изключения. Класът ClientRequestException се хвърля при кодове 4xx, ServerResponseException при 5xx, а IOException при мрежови грешки. Таймаутите се конфигурират чрез плъгина HttpTimeout, който задава време за изчакване на връзка, четене и запис. За повторни опити се използва плъгинът Retry с настройки за брой опити и закъснение.
Ktor използва тръбопроводна архитектура, където всяка заявка преминава през верига от обработвачи. Клиентът създава конфигурация на HttpClient с инсталирани плъгини и всяко извикване на метод get или post преминава през плъгините в реда на свързването им.
Обектът HttpClient се създава с двигател, специфичен за платформата: CIO за JVM и Android, Darwin за iOS и macOS, OkHttp за съвместимост с Android, Js за браузър. Двигателят може да бъде избран изрично или да се остави на автоматичен избор. Всяка заявка връща HttpResponse, който съдържа тялото на отговора, заглавките и статуса.
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
suspend fun fetchUsers(): List<User> {
return client.get("https://api.example.com/users").body()
}
Инсталирането на Ktor се извършва чрез Gradle или Maven. В мултиплатформени проекти зависимостите се посочват в sourceSets за всяка цел. Ktor се разпространява чрез Maven Central.
В build.gradle.kts добавете зависимостта ktor-client-core за споделен код и двигателя за конкретната платформа. Версията на Ktor се задава чрез променлива в gradle.properties. Ktor 3.x изисква Kotlin 2.0+ и поддържа компилатора K2.
val ktorVersion = "3.0.3"
dependencies {
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
}
За iOS се използва двигателят Darwin, който обвива родния URLSession. В Kotlin Multiplatform това позволява максимална производителност и интеграция със системните механизми за кеширане на iOS. Двигателят се добавя като отделна зависимост в iOS sourceSet.
Важна характеристика на Ktor — поддръжка на различни формати за сериализация чрез ContentNegotiation. Освен JSON, плъгинът поддържа Protobuf, CBOR, XML и персонализирани формати. За сериализация се използват библиотеките kotlinx.serialization или Jackson и разработчикът може да превключва между тях без да променя кода на заявките.
Примерите по-долу демонстрират типични сценарии за работа с Ktor клиента: основна GET заявка, изпращане на данни и работа с мултиплатформен код.
Проста GET заявка с автоматична десериализация на отговора в data-клас. Ktor използва плъгина ContentNegotiation с kotlinx.serialization за преобразуване на JSON в обекти. Кодът е сбит и типобезопасен.
@Serializable
data class Post(
val id: Int,
val title: String,
val body: String
)
suspend fun getPosts(): List<Post> {
val response = client.get("https://jsonplaceholder.typicode.com/posts")
return response.body()
}
POST заявката в Ktor изпраща data-клас като JSON тяло чрез метода post с contentType и setBody. Плъгинът ContentNegotiation автоматично сериализира обекта в JSON низ. Отговорът може да бъде обработен синхронно или асинхронно.
suspend fun createPost(): Post {
val newPost = Post(
id = 0,
title = "Нова публикация",
body = "Съдържание на публикацията"
)
val response = client.post("https://jsonplaceholder.typicode.com/posts") {
contentType(ContentType.Application.Json)
setBody(newPost)
}
return response.body()
}
Методът submitFormWithBinaryData в Ktor позволява изпращане на файлове и формуляри в multipart формат. Ktor автоматично разделя данните на части и добавя заглавки. За проследяване на напредъка се използва onUpload, който получава байтове на изпратените данни.
suspend fun uploadFile(fileBytes: ByteArray) {
client.submitFormWithBinaryData(
url = "https://api.example.com/upload",
formData = formData {
append("file", fileBytes, Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=\"photo.png\"")
})
}
)
}
Изборът между Ktor и Retrofit зависи от архитектурата на проекта и изискванията за мултиплатформеност. Retrofit остава стандарт за проекти само за Android, докато Ktor е по-добрият избор за Kotlin Multiplatform.
Ktor също така предоставя вградена поддръжка за WebSocket и SSE (Server-Sent Events), което го прави удобен за приложения в реално време. Retrofit не поддържа WebSocket директно — за това е необходима отделна библиотека OkHttp WebSocket. Ktor също се конфигурира по-лесно за различни среди благодарение на плъгин системата, където всеки плъгин отговаря за една функция.
Плъгинът Auth в Ktor поддържа основно удостоверяване, Bearer токени, Digest и OAuth2. Конфигурирането на удостоверяване се извършва декларативно: разработчикът посочва доставчик, източник на токен и обхват на действие. Ktor автоматично добавя заглавки за удостоверяване към заявките и може да обнови токена при изтичането му.
Ако проектът използва Kotlin Multiplatform със споделен код на iOS и Android, Ktor е единственият вариант, който работи на двете платформи без допълнителни слоеве. Retrofit е тясно обвързан с OkHttp и JVM, което го прави неподходящ за iOS.
За проекти само за Android, Retrofit предоставя по-зряло API, повече конвертори и OkHttp интерсептори. Ktor работи и в този сценарий, но неговата плъгин екосистема е по-слабо развита. И двете библиотеки поддържат корутини и предлагат сравнима производителност.
| Критерий | Ktor | Retrofit |
|---|---|---|
| Мултиплатформеност | iOS, Android, JVM, JS, Native | Само JVM и Android |
| HTTP двигател | CIO, Darwin, OkHttp, Js | OkHttp |
| Конвертори | kotlinx.serialization, Jackson | Gson, Moshi, Jackson, Protobuf |
| Архитектура | Тръбопровод с плъгини | Анотации с генериране на код |
| Разработчик | JetBrains | Square |
Често задавани въпроси
Ktor — мултиплатформен HTTP клиент на корутини от JetBrains. Retrofit — Android библиотека от Square, базирана на OkHttp. Ktor работи на iOS, Android, JS и Native, а Retrofit — само на JVM.
Да, Ktor поддържа iOS чрез двигателя Darwin, който използва родния URLSession. Това осигурява максимална производителност и коректна работа със системния кеш на iOS. Кодът на клиента остава споделен между платформите.
Ktor поддържа двигатели: CIO (JVM/Android), Darwin (iOS/macOS), OkHttp (Android), Js (браузър), Jetty, Netty, Tomcat (сървърни). Двигателят може да бъде избран изрично или да се остави на автоматичен избор по подразбиране.
Да, Ktor има вградена поддръжка за WebSocket както от страна на клиента, така и на сървъра. За клиента се използва плъгинът WebSockets, който позволява установяване на двупосочна връзка и обмен на съобщения в реално време.
Грешките се обработват чрез try-catch около suspend извиквания. Ktor хвърля изключения ClientRequestException за 4xx, ServerResponseException за 5xx и IOException за мрежови грешки. Препоръчва се използване на тип Result за уеднаквяване.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също