عميل HTTP بلغة Kotlin: إجراء الطلبات بشكل صحيح من الألف إلى الياء
\nالتطوير الحديث بلغة Kotlin لا يمكن تصوره دون التفاعل مع الخوادم البعيدة. سواء كان تطبيق جوال على Android أو حلاً خادمياً على Ktor - فإن طلبات HTTP هي أساس تبادل البيانات. في هذه المقالة، سنشرح كيفية إنشاء عملاء HTTP بلغة Kotlin باستخدام أفضل الممارسات والمكتبات الشائعة والنهج الحديث مع coroutines. ستتعلم كيفية إجراء طلبات GET وPOST، ومعالجة الأخطاء، والعمل مع JSON، وبناء بنية موثوقة لطبقة الشبكة.
\n\nلماذا Kotlin مثالية لعملاء HTTP؟
\nتقدم Kotlin بناء جملة موجزاً، وأماناً للقيم الخالية (null safety)، وتوافقاً كاملاً مع نظام Java البيئي. بفضل coroutines، تصبح الطلبات غير المتزامنة بديهية دون الحاجة إلى استدعاءات رجعية (callbacks) ضخمة. يمكنك كتابة كود تسلسلي يتم تنفيذه بشكل غير متزامن - مما يبسط القراءة وتصحيح الأخطاء بشكل كبير. بالإضافة إلى ذلك، تُستخدم Kotlin بنشاط في تطوير Android، حيث تعتبر طلبات الشبكة مهمة يومية.
\n\nالمكتبات الرئيسية لـ HTTP في Kotlin
\nحالياً، هناك ثلاثة نهج شائعة:
\n- \n
- Ktor Client - عميل متعدد المنصات من JetBrains. يدعم JVM وAndroid وiOS وJS وNative. مثالي للمشاريع التي تحتاج إلى قاعدة كود موحدة. \n
- OkHttp + Retrofit - مجموعة تقليدية لـ Android/JVM. OkHttp مسؤول عن العمل منخفض المستوى مع الشبكة، بينما يقوم Retrofit بتوليد واجهات مطبوعة (typed interfaces). \n
- Fuel - مكتبة خفيفة ذات نهج وظيفي. مناسبة للمشاريع الصغيرة. \n
في هذه المقالة، سنركز على Ktor وOkHttp لأنهما يغطيان 90% من السيناريوهات.
\n\nإعداد المشروع والطلبات الأولى
\nلنبدأ بإضافة التبعيات. إذا كنت تستخدم Gradle (Kotlin DSL)، قم بتضمين Ktor Client:
\ndependencies {\n implementation("io.ktor:ktor-client-core:2.3.7")\n implementation("io.ktor:ktor-client-cio:2.3.7") // محرك CIO\n implementation("io.ktor:ktor-client-content-negotiation:2.3.7")\n implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")\n}\nبالنسبة لـ OkHttp، ستكون التبعيات كالتالي:
\ndependencies {\n implementation("com.squareup.okhttp3:okhttp:4.12.0")\n implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")\n implementation("com.google.code.gson:gson:2.10.1")\n}\n\nطلب GET مع Ktor Client
\nلنقم بإنشاء عميل بسيط وتنفيذ طلب GET إلى API عام:
\nimport io.ktor.client.*\nimport io.ktor.client.request.*\nimport io.ktor.client.statement.*\n\nsuspend fun fetchData(): String {\n val client = HttpClient()\n val response: HttpResponse = client.get("https://jsonplaceholder.typicode.com/posts/1")\n val body = response.bodyAsText()\n client.close()\n return body\n}\n\n// الاستخدام في coroutine\nfun main() = runBlocking {\n println(fetchData())\n}\nلاحظ: suspend هي كلمة مفتاحية في Kotlin للدوال القابلة للإيقاف. هذا يسمح بتنفيذ الطلب دون حظر الخيط.
طلب GET مع OkHttp
\nمثال مماثل باستخدام OkHttp يبدو كالتالي:
\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\n\nfun fetchDataSync(): String {\n val client = OkHttpClient()\n val request = Request.Builder()\n .url("https://jsonplaceholder.typicode.com/posts/1")\n .build()\n client.newCall(request).execute().use { response ->\n return response.body?.string() ?: "خطأ"\n }\n}\n\n// الاستدعاء في خيط عادي (حظر)\nfun main() {\n println(fetchDataSync())\n}\nOkHttp متزامن بشكل افتراضي، ولكن يمكن تكييفه بسهولة مع coroutines باستخدام suspendCancellableCoroutine.
طلبات POST والعمل مع JSON
\nإرسال البيانات هي ثاني أهم عملية. دعنا نرى كيفية إرسال JS