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 використовує pipeline-архітектуру, де кожен запит проходить через ланцюжок обробників. Клієнт створює конфігурацію 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-only проектів, тоді як 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-only проектів 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 |
| Архітектура | Pipeline з плагінами | Анотації з кодогенерацією |
| Розробник | 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також