Ktor — este un client HTTP asincron și un framework server pentru Kotlin, care suportă dezvoltarea multi-platformă. Biblioteca este construită pe corutine Kotlin și funcționează pe JVM, iOS, Android, JS și Native. Conform datelor repository-ului Ktor pe GitHub, proiectul este dezvoltat activ de echipa JetBrains. Ktor oferă o arhitectură modulară cu un sistem de pluginuri pentru configurarea flexibilă a conexiunilor HTTP.
Puncte cheie
Ktor — este un framework pentru crearea de clienți HTTP și servere în limbajul Kotlin, dezvoltat de compania JetBrains. Spre deosebire de bibliotecile tradiționale, Ktor a fost proiectat de la început pentru dezvoltare multi-platformă și funcționează pe toate platformele suportate de Kotlin.
Ktor utilizează abordarea handlerelor intermediare, inspirată de arhitectura Kodein și Express.js. Fiecare cerere trece printr-un pipeline de funcții handler care pot modifica cererea și răspunsul. Aceasta asigură o flexibilitate care nu este disponibilă în bibliotecile cu arhitectură rigidă bazată pe adnotări.
Versiunea curentă Ktor 3.0 include suport pentru Kotlin 2.0, compilatorul K2 și un nou motor CIO (Coroutine I/O) cu performanță îmbunătățită. Biblioteca este distribuită sub licența Apache 2.0 și este disponibilă pentru uz comercial fără restricții.
Partea client a Ktor este construită complet pe corutine Kotlin, ceea ce asigură o executare asincronă eficientă a cererilor fără a bloca firele de execuție. Partea server permite crearea de servere HTTP cu rutare, procesare a cererilor și conexiuni WebSocket.
Ktor utilizează o arhitectură cu pluginuri: toate funcțiile suplimentare — logarea, serializarea, autentificarea — sunt conectate prin pluginuri. Acest lucru face biblioteca modulară și permite conectarea doar a componentelor necesare, reducând dimensiunea aplicației finale.
Datorită API-ului unificat pe toate platformele, dezvoltatorul nu trebuie să învețe diferiți clienți HTTP pentru iOS și Android. Într-un proiect multi-platformă, codul stratului de rețea este complet partajat, iar implementarea specifică platformei este ascunsă în spatele motorului HttpClient. Acest lucru reduce timpul de dezvoltare și numărul de erori legate de diferențele dintre platforme.
Ktor oferă un set de funcționalități care îl fac o alegere atractivă pentru proiectele moderne Kotlin, în special cele multi-platformă.
Ktor funcționează pe JVM, Android, iOS, macOS, Windows, Linux, JavaScript și Wasm. Același cod al clientului HTTP rulează pe toate platformele fără modificări. Acesta este un avantaj cheie față de bibliotecile legate de OkHttp sau URLSession.
Corutinele Kotlin asigură asincronizarea naturală fără callback-uri. Fiecare cerere este o funcție suspend care poate fi apelată din orice corutină. Ktor suportă streamingul răspunsurilor prin Flow, ceea ce este convenabil pentru conexiuni lungi și WebSocket.
Pluginurile Ktor se conectează prin blocul install și se configurează separat. Pluginurile principale: ContentNegotiation pentru serializare, Logging pentru logare, Auth pentru autentificare și WebSockets pentru comunicare bidirecțională. Fiecare plugin poate fi activat sau dezactivat independent.
Gestionarea erorilor în Ktor se bazează pe excepții. Clasa ClientRequestException este aruncată la codurile 4xx, ServerResponseException la 5xx, iar IOException la erori de rețea. Timeout-urile se configurează prin pluginul HttpTimeout, care stabilește timpul de așteptare pentru conexiune, citire și scriere. Pentru reîncercări se utilizează pluginul Retry cu setări pentru numărul de încercări și întârziere.
Ktor utilizează o arhitectură pipeline, unde fiecare cerere trece printr-un lanț de handlere. Clientul creează o configurație HttpClient cu pluginurile instalate, iar fiecare apel al metodei get sau post trece prin pluginuri în ordinea conectării lor.
Obiectul HttpClient este creat cu un motor specific platformei: CIO pentru JVM și Android, Darwin pentru iOS și macOS, OkHttp pentru compatibilitate cu Android, Js pentru browser. Motorul poate fi selectat explicit sau se poate lăsa selecția automată. Fiecare cerere returnează HttpResponse, care conține corpul răspunsului, antetele și statusul.
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
suspend fun fetchUsers(): List<User> {
return client.get("https://api.example.com/users").body()
}
Instalarea Ktor se face prin Gradle sau Maven. În proiectele multi-platformă, dependențele se specifică în sourceSets pentru fiecare target. Ktor este distribuit prin Maven Central.
În build.gradle.kts adăugați dependența ktor-client-core pentru codul partajat și motorul pentru platforma specifică. Versiunea Ktor se setează printr-o variabilă în gradle.properties. Ktor 3.x necesită Kotlin 2.0+ și suportă compilatorul 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")
}
Pentru iOS se utilizează motorul Darwin, care încapsulează URLSession-ul nativ. În Kotlin Multiplatform, aceasta permite obținerea performanței maxime și integrării cu mecanismele de cache ale sistemului iOS. Motorul se adaugă ca dependență separată în sourceSet-ul iOS.
O caracteristică importantă a Ktor — suportul pentru diferite formate de serializare prin ContentNegotiation. Pe lângă JSON, pluginul suportă Protobuf, CBOR, XML și formate personalizate. Pentru serializare se utilizează bibliotecile kotlinx.serialization sau Jackson, iar dezvoltatorul poate comuta între ele fără a modifica codul cererilor.
Exemplele de mai jos demonstrează scenarii tipice de lucru cu clientul Ktor: cererea GET de bază, trimiterea de date și lucrul cu cod multi-platformă.
O cerere GET simplă cu deserializarea automată a răspunsului într-o clasă de date. Ktor utilizează pluginul ContentNegotiation cu kotlinx.serialization pentru conversia JSON-ului în obiecte. Codul este concis și tip-securizat.
@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()
}
Cererea POST în Ktor trimite o clasă de date ca corp JSON prin metoda post cu contentType și setBody. Pluginul ContentNegotiation serializează automat obiectul într-un șir JSON. Răspunsul poate fi procesat sincron sau asincron.
suspend fun createPost(): Post {
val newPost = Post(
id = 0,
title = "Post nou",
body = "Conținutul postării"
)
val response = client.post("https://jsonplaceholder.typicode.com/posts") {
contentType(ContentType.Application.Json)
setBody(newPost)
}
return response.body()
}
Metoda submitFormWithBinaryData în Ktor permite trimiterea fișierelor și formularelor în format multipart. Ktor împarte automat datele în părți și adaugă antete. Pentru urmărirea progresului se utilizează onUpload, care primește octeții datelor trimise.
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\"")
})
}
)
}
Alegerea între Ktor și Retrofit depinde de arhitectura proiectului și de cerințele de multi-platformă. Retrofit rămâne standardul pentru proiectele doar pe Android, în timp ce Ktor este alegerea mai bună pentru Kotlin Multiplatform.
Ktor oferă, de asemenea, suport integrat pentru WebSocket și SSE (Server-Sent Events), ceea ce îl face convenabil pentru aplicații în timp real. Retrofit nu suportă WebSocket direct — pentru aceasta este necesară o bibliotecă separată OkHttp WebSocket. Ktor se configurează și mai ușor pentru diferite medii datorită sistemului de pluginuri, unde fiecare plugin răspunde pentru o singură funcție.
Pluginul Auth în Ktor suportă autentificarea de bază, token-urile Bearer, Digest și OAuth2. Configurarea autentificării se face declarativ: dezvoltatorul specifică furnizorul, sursa token-ului și domeniul de acțiune. Ktor adaugă automat antetele de autentificare la cereri și poate reîmprospăta token-ul la expirare.
Dacă proiectul utilizează Kotlin Multiplatform cu cod partajat pe iOS și Android, Ktor este singura opțiune care funcționează pe ambele platforme fără straturi suplimentare. Retrofit este strict legat de OkHttp și JVM, ceea ce îl face nepotrivit pentru iOS.
Pentru proiectele doar pe Android, Retrofit oferă un API mai matur, un număr mai mare de convertoare și interceptoare OkHttp. Ktor funcționează și în acest scenariu, dar ecosistemul său de pluginuri este mai puțin extins. Ambele biblioteci suportă corutinele și oferă performanță comparabilă.
| Criteriu | Ktor | Retrofit |
|---|---|---|
| Multi-platformă | iOS, Android, JVM, JS, Native | Doar JVM și Android |
| Motor HTTP | CIO, Darwin, OkHttp, Js | OkHttp |
| Convertoare | kotlinx.serialization, Jackson | Gson, Moshi, Jackson, Protobuf |
| Arhitectură | Pipeline cu pluginuri | Adnotări cu generare de cod |
| Dezvoltator | JetBrains | Square |
Întrebări frecvente
Ktor — client HTTP multi-platformă pe corutine de la JetBrains. Retrofit — bibliotecă Android de la Square bazată pe OkHttp. Ktor funcționează pe iOS, Android, JS și Native, iar Retrofit — doar pe JVM.
Da, Ktor suportă iOS prin motorul Darwin, care utilizează URLSession-ul nativ. Aceasta asigură performanță maximă și funcționarea corectă cu cache-ul de sistem iOS. Codul clientului rămâne partajat între platforme.
Ktor suportă motoarele: CIO (JVM/Android), Darwin (iOS/macOS), OkHttp (Android), Js (browser), Jetty, Netty, Tomcat (server). Motorul poate fi selectat explicit sau se poate lăsa selecția automată implicită.
Da, Ktor are suport integrat pentru WebSocket atât pe client, cât și pe server. Pentru client se utilizează pluginul WebSockets, care permite stabilirea unei conexiuni bidirecționale și schimbul de mesaje în timp real.
Erorile sunt gestionate prin try-catch în jurul apelurilor suspend. Ktor aruncă excepțiile ClientRequestException pentru 4xx, ServerResponseException pentru 5xx și IOException pentru erori de rețea. Se recomandă utilizarea tipului Result pentru unificare.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și