Το Ktor είναι ένας ασύγχρονος HTTP πελάτης για Kotlin, που αναπτύχθηκε από την JetBrains ως μέρος του ομώνυμου πλαισίου για ανάπτυξη διακομιστή και πελάτη. Το Ktor είναι χτισμένο πάνω σε coroutines της Kotlin και υποστηρίζει πολλαπλές πλατφόρμες. Σύμφωνα με τα δεδομένα της JetBrains, 2025, το Ktor παρέχει εγγενή ενσωμάτωση με το οικοσύστημα Kotlin χωρίς αντανάκλαση (reflection) και πρόσθετες εξαρτήσεις.
Κύρια σημεία
Το Ktor είναι ένα πλαίσιο για τη δημιουργία ασύγχρονων εφαρμογών διακομιστή και πελάτη σε Kotlin, που δημιουργήθηκε από την JetBrains. Το Ktor Client — το τμήμα πελάτη του πλαισίου, που παρέχει έναν HTTP πελάτη με πλήρη υποστήριξη για coroutines της Kotlin, πολλαπλές πλατφόρμες (JVM, Native, JS) και αρθρωτή αρχιτεκτονική βασισμένη σε plugins.
Το Ktor εμφανίστηκε το 2018 ως εναλλακτική λύση για Retrofit και OkHttp σε έργα Kotlin-first. Σε αντίθεση με το Retrofit, που μετέφερε την προσέγγιση Java με σχολιασμούς (annotations), το Ktor Client χρησιμοποιεί Kotlin DSL για τη διαμόρφωση αιτημάτων — χωρίς σχολιασμούς και αντανάκλαση. Αυτό καθιστά τον κώδικα πιο ευανάγνωστο και ασφαλή ως προς τους τύπους για προγραμματιστές Kotlin.
Σύμφωνα με την έρευνα Kotlin Multiplatform 2024, το Ktor Client χρησιμοποιείται στο 35% των έργων Kotlin Multiplatform Mobile (KMM), καθιστώντας το τον δεύτερο δημοφιλέστερο HTTP πελάτη μετά το OkHttp στην κοινότητα Kotlin. Το Ktor προτιμάται σε έργα όπου η υποστήριξη πολλαπλών πλατφορμών και η εγγενής ενσωμάτωση με το οικοσύστημα Kotlin είναι σημαντικές.
Η αρχιτεκτονική του Ktor Client βασίζεται σε έναν αγωγό (pipeline) από plugins. Κάθε αίτημα διέρχεται από μια ακολουθία εγκατεστημένων plugins, τα οποία μπορούν να τροποποιήσουν το αίτημα, την απόκριση ή να εκτελέσουν παρεπόμενες ενέργειες — καταγραφή, συμπίεση, σειριοποίηση, αυθεντικοποίηση.
Κατά τη δημιουργία ενός HTTP πελάτη μέσω του μπλοκ HttpClient { } DSL, καθορίζετε τη μηχανή (OkHttp, Android, CIO, Darwin) και εγκαθιστάτε plugins. Κάθε μηχανή υλοποιεί την αποστολή αιτημάτων χαμηλού επιπέδου για μια συγκεκριμένη πλατφόρμα: στο Android χρησιμοποιείται η μηχανή OkHttp, στο iOS — Darwin (URLSession), στο Desktop — CIO (Coroutine-based I/O). Το HttpClient επιλέγει αυτόματα τη βέλτιστη μηχανή για την τρέχουσα πλατφόρμα.
Το αίτημα στο Ktor Client εκτελείται μέσω της συνάρτησης suspend, που σημαίνει πλήρη ενσωμάτωση με τα coroutines. Χωρίς Callback, RxJava ή LiveData — μόνο σειριακός κώδικας με suspend που λειτουργεί ασύγχρονα χωρίς αποκλεισμό του νήματος.
Ο αγωγός Ktor αποτελείται από φάσεις: πρώτα το αίτημα διέρχεται από τα εγκατεστημένα plugins (π.χ. ContentNegotiation για JSON, Logging για καταγραφές), στη συνέχεια η μηχανή εκτελεί το HTTP αίτημα, και η απόκριση διέρχεται ξανά από τα plugins για αποσειριοποίηση. Κάθε plugin είναι μια συνάρτηση suspend που εκτελείται στο coroutine του αγωγού.
Ένα σημαντικό πλεονέκτημα του αγωγού Ktor είναι η δυνατότητα υπό όρους επεξεργασίας. Το plugin μπορεί να ελέγξει το URL ή τις κεφαλίδες του αιτήματος και να παραλείψει την επεξεργασία εάν δεν πληρούται η συνθήκη. Για παράδειγμα, το ContentEncoding με gzip εφαρμόζεται μόνο σε αποκρίσεις που περιέχουν την κεφαλίδα Content-Encoding: gzip, και το Auth ενεργοποιείται μόνο για προστατευμένα endpoints χωρίς να επηρεάζει τα δημόσια API.
Αυτή η προσέγγιση αγωγού επιτρέπει ευέλικτο συνδυασμό plugins: μπορείτε να εγκαταστήσετε το ContentNegotiation με JSON, να προσθέσετε Auth με Bearer token, να ενεργοποιήσετε τη συμπίεση ContentEncoding και το HttpTimeout — και όλα θα λειτουργούν μαζί στη σωστή σειρά. Η σειρά εγκατάστασης των plugins έχει σημασία: το πρώτο εγκατεστημένο θα επεξεργαστεί το αίτημα νωρίτερα από τα υπόλοιπα.
Τα Plugins — το αρθρωτό σύστημα επεκτάσεων του Ktor, που αντικαθιστά τους σχολιασμούς Retrofit και τους παρεμβολείς OkHttp. Κάθε plugin λύνει μια συγκεκριμένη εργασία και εγκαθίσταται μέσω της συνάρτησης install() στο μπλοκ HttpClient. Το Ktor παρέχει ενσωματωμένα plugins, καθώς και επιτρέπει τη δημιουργία προσαρμοσμένων.
| Plugin | Σκοπός |
|---|---|
| ContentNegotiation | Σειριοποίηση και αποσειριοποίηση JSON, XML μέσω Kotlinx Serialization |
| Logging | Καταγραφή αιτημάτων και αποκρίσεων με διαμόρφωση επιπέδου |
| Auth | Αυθεντικοποίηση: Basic, Bearer, Digest με αυτόματη ανανέωση token |
| HttpTimeout | Διαμόρφωση χρονικών ορίων σύνδεσης, ανάγνωσης και αιτήματος |
| ContentEncoding | Διαφανής συμπίεση gzip και deflate |
| DefaultRequest | Ορισμός προεπιλεγμένων τιμών για όλα τα αιτήματα |
Για συγκεκριμένες εργασίες δημιουργείται ένα προσαρμοσμένο plugin μέσω του createClientPlugin. Το plugin μπορεί να παρεμβάλει το αίτημα (onRequest), την απόκριση (onResponse) ή να διαχειρίζεται σφάλματα (onError). Αυτό αντικαθιστά πλήρως τον Interceptor από το OkHttp, αλλά με τυποποιημένο Kotlin-API και υποστήριξη συναρτήσεων suspend.
Τα προσαρμοσμένα plugins είναι χρήσιμα για την προσθήκη μετρήσεων, αυτόματης λογικής επανάληψης, ιχνηλάτησης αιτημάτων ή A/B δοκιμών endpoints. Σε αντίθεση με τους παρεμβολείς OkHttp, τα plugins Ktor είναι γραμμένα σε Kotlin και λειτουργούν στο πλαίσιο coroutine, γεγονός που απλοποιεί τη διαχείριση σφαλμάτων και χρονικών ορίων.
Για τον εντοπισμό σφαλμάτων αιτημάτων χρησιμοποιείται το plugin Logging με επίπεδο ALL, HEADERS ή BODY. Το Logging εμφανίζει τη μέθοδο, URL, κατάσταση, κεφαλίδες και το σώμα του αιτήματος και της απόκρισης. Σε αντίθεση με το HttpLoggingInterceptor από το OkHttp, το Ktor Logging λειτουργεί ασύγχρονα και μπορεί να ρυθμιστεί για φιλτράρισμα ανά επίπεδο καταγραφής (ERROR, WARN, INFO, DEBUG) χωρίς διακοπή της εφαρμογής για αλλαγή διαμόρφωσης.
Ας εξετάσουμε ένα βασικό αίτημα GET μέσω Ktor Client. Δημιουργείται ένα HttpClient με εγκατεστημένο το plugin ContentNegotiation για JSON. Το αίτημα εκτελείται μέσω της συνάρτησης suspend get(), το αποτέλεσμα αποσειριοποιείται αυτόματα σε data class.
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 καθιστά τον κώδικα σειριακό και ευανάγνωστο.
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 — δύο βασικά plugins για διαμόρφωση. Το HttpTimeout ορίζει χρονικά όρια, ενώ το DefaultRequest καθορίζει κεφαλίδες και παραμέτρους URL για όλα τα αιτήματα, εξαλείφοντας την επανάληψη κώδικα σε κάθε κλήση.
val client = HttpClient {
install(HttpTimeout) {
connectTimeoutMillis = 15000
requestTimeoutMillis = 30000
}
install(DefaultRequest) {
url("https://api.github.com/")
header("Accept", "application/json")
}
}
Η υποστήριξη πολλαπλών πλατφορμών — το κύριο πλεονέκτημα του 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 — καθαρή υλοποίηση coroutine χωρίς εξωτερικές εξαρτήσεις. Για στόχους Web χρησιμοποιείται JsEngine ή BrowserEngine που λειτουργεί μέσω fetch API.
Χάρη στο ενιαίο API σε όλες τις πλατφόρμες, ο κώδικας φόρτωσης δεδομένων φαίνεται ίδιος σε Android, iOS και Desktop. Αυτό μειώνει την επανάληψη κώδικα κατά 60–80% σε έργα KMM σε σύγκριση με ξεχωριστές υλοποιήσεις σε Retrofit (Android) και URLSession (iOS). Τα plugins επίσης λειτουργούν σε όλες τις πλατφόρμες χωρίς αλλαγές.
Παράβλεψη κλεισίματος του HttpClient — συνηθισμένο λάθος στο Ktor. Το HttpClient υλοποιεί το Closeable και πρέπει να κλείσει κατά τον τερματισμό της εφαρμογής μέσω του client.close(). Στο Android αυτό γίνεται στο onDestroy() της Activity ή στο ViewModel.onCleared(). Ένας μη κλεισμένος πελάτης οδηγεί σε διαρροή coroutines και νημάτων μηχανής.
Λανθασμένη σειρά plugins μπορεί να διαταράξει την επεξεργασία αιτημάτων. Για παράδειγμα, το ContentNegotiation πρέπει να εγκατασταθεί πριν από το DefaultRequest για να εφαρμόζεται σωστά ο τύπος περιεχομένου. Το Logging συνιστάται να εγκαθίσταται τελευταίο για να καταγράφεται η τελική έκδοση του αιτήματος μετά από όλες τις τροποποιήσεις. Πειραματιστείτε με τη σειρά εάν τα plugins συμπεριφέρονται απροσδόκητα.
Έλλειψη διαχείρισης εξαιρέσεων σε συναρτήσεις suspend. Το Ktor ρίχνει εξαιρέσεις IOException σε σφάλματα δικτύου και ClientRequestException σε καταστάσεις HTTP 4xx. Το μπλοκ try-catch είναι υποχρεωτικό για κάθε κλήση get(), post() και άλλων μεθόδων. Χρησιμοποιήστε το HttpResponseValidator στο μπλοκ HttpClient για καθολική διαχείριση σφαλμάτων χωρίς επανάληψη try-catch σε κάθε μέθοδο.
Συχνές Ερωτήσεις
Το Ktor χρησιμοποιεί Kotlin DSL και plugins χωρίς σχολιασμούς και αντανάκλαση. Το Retrofit είναι χτισμένο σε σχολιασμούς Java και αντανάκλαση. Το Ktor υποστηρίζει πολλαπλές πλατφόρμες, το Retrofit — μόνο JVM/Android. Το Ktor λειτουργεί εγγενώς με coroutines, το Retrofit πρόσθεσε το suspend μέσω περιτυλίγματος.
Για Android η μηχανή OkHttp είναι βέλτιστη — παρέχει συμβατότητα με το οικοσύστημα OkHttp, ομάδα συνδέσεων, προσωρινή αποθήκευση και HTTP/2. Επιλέξτε την μέσω HttpClient(OkHttp) { }. Εναλλακτική — το CIOEngine ενσωματωμένο στο Ktor, αλλά είναι λιγότερο σταθερό στο Android.
Ναι, το Ktor υποστηρίζει HTTP/2 μέσω της αντίστοιχης μηχανής. Η μηχανή OkHttp κληρονομεί την υποστήριξη HTTP/2 από το OkHttp. Το DarwinEngine στο iOS υποστηρίζει HTTP/2 μέσω URLSession. Το CIOEngine υποστηρίζει HTTP/2 στην πλευρά διακομιστή. Η επιλογή μηχανής καθορίζει το επίπεδο υποστήριξης πρωτοκόλλου.
Χρησιμοποιήστε το plugin Auth με ρύθμιση bearer { }. Το plugin προσθέτει αυτόματα την κεφαλίδα Authorization σε κάθε αίτημα και μπορεί να ανανεώνει το token σε απόκριση 401 μέσω refreshTokens. Παράδειγμα: install(Auth) { bearer { loadTokens { BearerTokens(token, refreshToken) } } }.
Ναι, το Ktor Client λειτουργεί πλήρως στο iOS μέσω του DarwinEngine, που χρησιμοποιεί το URLSession. Όλα τα plugins, η σειριοποίηση και τα coroutines λειτουργούν στο iOS όπως και στο Android. Αυτό καθιστά το Ktor τον κύριο HTTP πελάτη για έργα Kotlin Multiplatform Mobile (KMM).
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης