Ktor هو عميل HTTP غير متزامن وإطار عمل خادم للغة Kotlin يدعم التطوير متعدد المنصات. تم بناء المكتبة على coroutines في 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 مبني بالكامل على coroutines في Kotlin، مما يوفر تنفيذاً غير متزامن فعالاً للطلبات دون حظر الخيوط. يسمح جزء الخادم بإنشاء خوادم HTTP مع توجيه ومعالجة الطلبات واتصالات WebSocket.
يستخدم Ktor بنية الإضافات: جميع الوظائف الإضافية — التسجيل والتسلسل والمصادقة — يتم توصيلها عبر الإضافات. هذا يجعل المكتبة معيارية ويسمح بتوصيل المكونات الضرورية فقط، مما يقلل حجم التطبيق النهائي.
بفضل API الموحد عبر جميع المنصات، لا يحتاج المطور إلى تعلم عملاء HTTP مختلفين لنظامي iOS و Android. في مشروع متعدد المنصات، يكون كود طبقة الشبكة مشتركاً بالكامل، ويكون التنفيذ الخاص بالمنصة مخفياً خلف محرك HttpClient. هذا يقلل وقت التطوير ويقلل عدد الأخطاء المرتبطة باختلافات المنصات.
Ktor يوفر مجموعة من الميزات التي تجعله خياراً جذاباً لمشاريع Kotlin الحديثة، خاصة متعددة المنصات.
Ktor يعمل على JVM و Android و iOS و macOS و Windows و Linux و JavaScript و Wasm. نفس كود عميل HTTP يعمل على جميع المنصات دون تغييرات. هذه ميزة رئيسية على المكتبات المرتبطة بـ OkHttp أو URLSession.
Coroutines في Kotlin توفر عدم التزامن الطبيعي بدون استدعاءات. كل طلب هو دالة suspend يمكن استدعاؤها من أي coroutine. يدعم 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. تتم إضافة المحرك كتبعية منفصلة في sourceSet لنظام iOS.
ميزة مهمة لـ Ktor هي دعم تنسيقات التسلسل المختلفة عبر ContentNegotiation. بالإضافة إلى JSON، تدعم الإضافة Protobuf و CBOR و XML والتنسيقات المخصصة. للتسلسل، يتم استخدام مكتبات kotlinx.serialization أو Jackson، ويمكن للمطور التبديل بينهما دون تغيير كود الطلبات.
الأمثلة أدناه توضح السيناريوهات النموذجية للعمل مع عميل Ktor: طلب GET أساسي، إرسال البيانات والعمل مع كود متعدد المنصات.
طلب GET بسيط مع فك تسلسل تلقائي للاستجابة في data class. يستخدم 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 class كنص 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 يعمل أيضاً في هذا السيناريو، لكن نظام الإضافات الخاص به أقل شمولاً. كلتا المكتبتين تدعمان coroutines وتعطيان أداءً مماثلاً.
| المعيار | 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 متعدد المنصات على coroutines من 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. سوف نقدم لك النصح ونقترح أفضل حل.