Kotlin وAPI: ثلاث ركائز للتطوير الحديث
\n\nهل تساءلت يومًا لماذا بعض التطبيقات تطير والبعض الآخر يتباطأ حتى على الأجهزة الرائدة؟ غالبًا ما يكمن السر ليس في العتاد، بل في كيفية تواصلها مع الخادم. إذا كنت تكتب بلغة Kotlin — سواء كان خلفية على Ktor أو تطبيق Android — عاجلاً أم آجلاً ستواجه خيارًا: REST أم GraphQL أم gRPC؟
\n\nفي PythonLib نحب تحليل التقنيات حتى أصغر التفاصيل. اليوم سنقوم بتحليل ثلاث طرق للتعامل مع API في Kotlin. لا ماء: فقط كود ومقارنة وحالات واقعية. هيا بنا!
\n\nREST API في Kotlin: الكلاسيكية التي لا تشيخ
\n\nREST يشبه البدلة السوداء: مناسبة في كل مكان، بسيطة ومفهومة. في Kotlin، هناك لاعبان رئيسيان لـ REST: Ktor (للجانب الخادم) وRetrofit (للجانب العميل).
\n\nخادم على Ktor: كتابة API في 5 دقائق
\n\nKtor هو إطار عمل من JetBrains، مصمم خصيصًا لـ Kotlin. إنه غير متزامن، خفيف ولا يفرض تبعيات غير ضرورية.
\n\n// build.gradle.kts\nimplementation("io.ktor:ktor-server-netty:2.3.7")\nimplementation("io.ktor:ktor-server-content-negotiation:2.3.7")\nimplementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")\n\nوالآن الخادم نفسه:
\n\nimport io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.routing.*\nimport io.ktor.server.response.*\nimport io.ktor.serialization.kotlinx.json.*\nimport io.ktor.server.plugins.contentnegotiation.*\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class User(val id: Int, val name: String, val email: String)\n\nfun main() {\n embeddedServer(Netty, port = 8080) {\n install(ContentNegotiation) {\n json()\n }\n routing {\n get("/api/users") {\n val users = listOf(\n User(1, "آنا", "anna@example.com"),\n User(2, "بوريس", "boris@example.com")\n )\n call.respond(users)\n }\n get("/api/users/{id}") {\n val id = call.parameters["id"]?.toIntOrNull()\n if (id != null) {\n call.respond(User(id, "اختبار", "test@example.com"))\n } else {\n call.respondText("معرف غير صحيح", status = io.ktor.http.HttpStatusCode.BadRequest)\n }\n }\n }\n }.start(wait = true)\n}\n\nهذا الكود هو REST API كامل في Kotlin مع نقطتي نهاية. يقوم Ktor بتسلسل البيانات إلى JSON تلقائيًا بفضل kotlinx.serialization.
عميل على Retrofit: الاتصال بأي API
\n\nRetrofit هو المعيار الفعلي لتطوير Android. يعمل بشكل مثالي مع Kotlin بفضل coroutines.
\n\n// build.gradle.kts\nimplementation("com.squareup.retrofit2:retrofit:2.9.0")\nimplementation("com.squareup.retrofit2:converter-gson:2.9.0")\nimplementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")\n\nنعلن عن الواجهة:
\n\ninterface ApiService {\n @GET("users")\n suspend fun getUsers(): List<User>\n\n @GET("users/{id}")\n suspend fun getUser(@Path("id") userId: Int): User\n\n @POST("users")\n suspend fun createUser(@Body user: User): User\n}\n\nننشئ العميل ونقوم بالطلب:
\n\nval retrofit = Retrofit.Builder()\n .baseUrl("https://api.example.com/")\n .addConverterFactory(GsonConverterFactory.create())\n .build()\n\nval service = retrofit.create(ApiService::class.java)\n\n// في coroutine\nGlobalScope.launch {\n val users = service.getUsers()\n println(users)\n}\n\nمزايا REST: البساطة، التخزين المؤقت عبر HTTP، مجتمع ضخم.
\nعيوب: over-fetching وunder-fetching للبيانات — غالبًا ما تحصل على أكثر أو أقل مما تحتاج.