عميل HTTP بلغة Kotlin: إجراء الطلبات بشكل صحيح
نادراً ما يخلو التطوير الحديث لنظام Android وخدمات الخلفية (backend) بلغة Kotlin من التفاعل مع واجهات برمجة التطبيقات (API) عن بُعد. إن إنشاء عميل HTTP موثوق هو مهمة أساسية، يعتمد عليها استقرار التطبيق بأكمله. في هذه المقالة، سنشرح كيفية إجراء طلبات HTTP بلغة Kotlin باستخدام أشهر مكتبتين: Ktor Client و OkHttp. ستتعلم كيفية إرسال طلبات GET و POST، ومعالجة JSON، وإدارة الأخطاء، وكتابة كود نظيف وقابل للصيانة.
لماذا Ktor Client هو اختيار مطور Kotlin الحديث
Ktor Client هو عميل HTTP غير متزامن (asynchronous)، تم إنشاؤه خصيصًا للغة Kotlin بواسطة فريق JetBrains. وهو يدعم بشكل كامل coroutines، مما يجعل الكود موجزًا وآمنًا. على عكس OkHttp، تم تصميم Ktor منذ البداية ليكون متعدد المنصات (multiplatform): حيث يعمل نفس الكود على Android و iOS و JVM و JS و Native.
تثبيت التبعيات (Dependencies)
للعمل مع Ktor Client، أضف التبعيات التالية إلى ملف build.gradle.kts:
dependencies { // العميل الأساسي implementation("io.ktor:ktor-client-core:2.3.7") // المحرك (Engine) لـ JVM (OkHttp أو CIO) implementation("io.ktor:ktor-client-okhttp:2.3.7") // لتسلسل JSON (Serialization) implementation("io.ktor:ktor-client-content-negotiation:2.3.7") implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7") // Kotlinx Serialization implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")}طلب GET بسيط
لنقم بإنشاء عميل HTTP وتنفيذ طلب GET إلى واجهة برمجة تطبيقات اختبارية (JSONPlaceholder):
import io.ktor.client.*import io.ktor.client.request.*import io.ktor.client.statement.*import kotlinx.coroutines.runBlocking
suspend fun fetchUser(userId: Int): String { val client = HttpClient { // الإعدادات الأساسية engine { // إعدادات محرك OkHttp } } val response: HttpResponse = client.get("https://jsonplaceholder.typicode.com/users/$userId") return response.bodyAsText()}
fun main() = runBlocking { val userData = fetchUser(1) println(userData)}لاحظ: fetchUser هي دالة suspend. هذا يسمح باستدعائها من داخل coroutine دون حظر (blocking) الخيط (thread).
طلب POST مع نص JSON
لإرسال البيانات بتنسيق JSON، سنقوم بتوصيل البرنامج المساعد (plugin) ContentNegotiation وتحديد data-class:
import io.ktor.client.*import io.ktor.client.call.*import io.ktor.client.plugins.contentnegotiation.*import io.ktor.client.request.*import io.ktor.http.*import io.ktor.serialization.kotlinx.json.*import kotlinx.serialization.Serializableimport kotlinx.serialization.json.Json
@Serializabledata class Post(val userId: Int, val id: Int? = null, val title: String, val body: String)
suspend fun createPost(post: Post): Post { val client = HttpClient { install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true prettyPrint = true }) } } val response: Post = client.post("https://jsonplaceholder.typicode.com/posts") { contentType(ContentType.Application.Json) setBody(post) }.body() client.close() return response}
fun main() = runBlocking { val newPost = Post(userId = 1, title = "Ktor Client", body = "يعمل بشكل ممتاز!") val createdPost = createPost(newPost) println(createdPost)}النقطة الأساسية: البرنامج المساعد ContentNegotiation يقوم تلقائيًا بتسلسل (serialize) الكائن إلى JSON وإلغاء تسلسله (deserialize) من الاستجابة مرة أخرى إلى data-class.
OkHttp — المعيار الموثوق لنظام Android
يظل OkHttp هو المعيار الفعلي (de facto standard) لطلبات الشبكة في تطوير Android. إنه سريع وموثوق ويدعم p