استخدام Kotlin لتطوير الخلفية: نظرة عامة سريعة
نشرت: 2022-03-11لست مضطرًا إلى تقديم Kotlin لمطوري Android الأصليين ، حيث أعلنت Google في مايو 2017 أنها ستكون اللغة الرسمية لتطوير Android. منذ ذلك الحين ، اكتسبت الكثير من الجاذبية باعتبارها الخيار الأساسي للغة لتطوير تطبيقات Android جديدة ولامعة. إنه يحل الكثير من نقاط الضعف في Java ، لذلك تتم كتابة التطبيقات الجديدة في الغالب ، ويتم إعادة كتابة التطبيقات القديمة فيه.
ليس هناك شك في أنها رائعة على الجانب الأمامي من التطبيقات ، وعندما تذكر Kotlin لأول مرة ، يربطها معظم الناس بنظام التشغيل Android OS. ومع ذلك ، في هذه المقالة ، سأتحدث عن Kotlin كلغة خلفية وأود أن أشارك قصتي حول إنشاء واجهة Kotlin الخلفية سريعة وموثوقة وغير متزامنة لمشروع هواية Android الخاص بي. لن أناقش ما هو المشروع ، لأنه خارج نطاق هذه المقالة ؛ بدلاً من ذلك ، سأركز على شرح سبب اختياري Kotlin ولماذا أعتقد أنها لغة رائعة لكتابة التطبيقات من جانب الخادم أو واجهات برمجة تطبيقات REST.
لماذا Kotlin؟
دعني أعود إلى بداية رحلتي. لطالما كانت لدي طموحات ريادية ، واعتقدت أن الخطوة الأولى على هذا الطريق هي إنشاء شيء بمفردي. لا شيء ضخم ، لا شيء يغير العالم ، مجرد شيء صغير يمكنني أنا وعائلتي وأصدقائي استخدامه. بعد أن كانت لدي فكرة معقولة ، قفزت إليها مباشرة وبدأت في تنفيذها. أول شيء تفعله في بداية أي مشروع هو اختيار أدواتك. بعد كل شيء ، يمكن أن توفر لك مجموعة الأدوات الصحيحة الكثير من الوقت والمال على المدى الطويل. لذلك هذا ما فعلته.
أنا في الأساس مطور جافا. لقد كتبت العديد من الأنظمة الخلفية وواجهات برمجة تطبيقات REST باستخدام Java و Spring ، وأعتقد أن هذين هما أداتان رائعتان للقيام بمثل هذه الأشياء. Java في حد ذاتها هي لغة شاملة ، ولكن مع Spring ، لا يوجد شيء لا يمكنك تنفيذه.
ومع ذلك ، لا يوجد سوى شعرة واحدة صغيرة في الحساء. الإسهاب. على الرغم من أن Spring والإصدارات الأحدث من Java تساعد كثيرًا في ذلك ، فلا يزال عليك التعامل مع الكثير من التعليمات البرمجية المعيارية. وكما قال لي رجل عظيم - الرمز الأكثر أمانًا والأكثر موثوقية وخاليًا من الأخطاء هو الكود الذي لم يتم تدوينه. خذ ، على سبيل المثال ، فئة Java التافهة هذه:
public class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
في رأيي ، هذا كثير من الكود للقول ببساطة ، "أريد فصلًا به حقلين للقراءة فقط." أسوأ جزء هو أنه تم إنشاء المُنشئ والطرق تلقائيًا. ومع ذلك ، عندما تقوم بمراجعة طلب سحب ، فإنك تقوم دائمًا بمراجعته لأنه ، حسنًا ، لا تعرف أبدًا ما إذا كان هذا هو ما تحتاجه أم لا. بالتأكيد ، يمكن اختصار هذا مع مكتبات الطرف الثالث مثل Lombok ، لكن ألن يكون من الجيد أن نقوم بذلك خارج الصندوق؟ دعونا نرى نفس هذه الفئة بالضبط في Kotlin:
class Person( val name: String, val age: Int )
إنه بالتأكيد أقصر وأبسط. المتغيرات نهائية حيث نستخدم كلمة val ؛ يتم إنشاء المُنشئ والمكتسبات في وقت الترجمة. إذا كنا نفضل ألا يكون لدينا كائن شخص غير قابل للتغيير ، فيمكننا ببساطة تغيير val إلى var ، و voila ، لدينا شخص قابل للتغيير ، وكل ما يتعين علينا فعله هو تغيير حرف واحد فقط.
الجزء الثاني المفضل لدي في فئة Java POJO البسيطة هو المتجاوزان equals()
و hashCode()
. يتم توليدها تلقائيًا في معظم الأوقات ، ولكن عليك دائمًا مراجعتها ، فقط للتأكد. الخبر السار هو أن Kotlin يمكنها التعامل مع هذا أيضًا. ما عليك سوى تغيير class
إلى data class
، وستحصل على equals()
و hashCode()
خارج المربع.
data class Person( val name: String, val age: Int )
باختصار ، على الرغم من أنني أحب Java ، إلا أنني أردت إنشاء منتج قابل للتطبيق بحد أدنى لمشروعي في أسرع وقت ممكن في وقت قصير. وفي حالة تطوير البرمجيات ، فإن أبسط طريقة لتحقيق ذلك هي كتابة كود أقل. وبالتالي ، استمر بحثي عن لغة أفضل لتطوير الخلفية. مع وضع هذه الفكرة في الاعتبار ، انتقلت أولاً نحو Node.js. له بعض المزايا المهمة - بضعة أسطر وخادم Express الخاص بك قيد التشغيل ، والاستماع على المنفذ 8080 ، والاستجابة باستخدام Hello World! في كل مرة ترسل فيها طلب الحصول.
let express = require('express') let app = express(); app.get('/', (req, res) => res.send('Hello World!')); app.listen(8080);
سهل وبسيط وسريع. فقط ما تتوقعه من إحدى لغات البرمجة الأكثر شيوعًا. أنا أستمتع بالعمل مع JavaScript ، ولحظة وجيزة ، اعتقدت أنني وجدت الأداة الصحيحة ، ولكن بعد ذلك شعرت بالضيق من حقيقة أن JavaScript مكتوب ديناميكيًا. لا تفهموني خطأ ، أعتقد أن الكتابة الديناميكية رائعة في الواجهة الأمامية ، ولكن من واقع خبرتي ، فإن وجود نهاية خلفية مكتوبة بشكل ثابت يمنحك ببساطة ثقة إضافية في أن خادمك أقل عرضة للتعطل في وقت التشغيل بسبب عدم تطابق النوع . ودعونا نكون صادقين هنا ، عندما تخدم نهايتك الخلفية مئات الآلاف من المستخدمين ، فأنت لا تريد أن يحدث ذلك حقًا. ومع ذلك ، قدمت Node.js ميزة واحدة رائعة أردت الاحتفاظ بها ، وهي القدرة على كتابة تعليمات برمجية وخدمات غير متزامنة بسهولة.
مع وضع هذه المتطلبات في الاعتبار ، اخترت كتابة النهاية الخلفية لـ Kotlin Android أيضًا في Kotlin.
Kotlin: نظرة عامة سريعة
بالنسبة لأولئك الذين لم يسمعوا بها من قبل ، فإن Kotlin هي لغة برمجة مفتوحة المصدر ومكتوبة بشكل ثابت تدعم كلاً من البرمجة الشيئية والوظيفية. يوفر بناء جملة ومفاهيم مشابهة مثل C # أو Java أو Scala ويستهدف بشكل أساسي JVM ولكن يحتوي أيضًا على متغيرات تستهدف JavaScript أو كود أصلي. إنه مشابه جدًا لجافا في أن Kotlin / JVM يجمعان وصولاً إلى Java bytecode ، لذلك بالنسبة لمهندسي النهاية الخلفية الذين لديهم خلفية JVM ، سيكون من السهل فهم Kotlin.

كما تنص صفحتها الرسمية ، فإن الهدف من Kotlin ليس أن تكون فريدًا ولكن أن تستمد الإلهام وأفضل الممارسات من عقود من تطوير اللغة. يمكن استخدامه مع أي Java IDE أو من سطر الأوامر ، لكنني شخصياً أفضل استخدامه مع IntelliJ وأوصي باستخدامه. يقوم فريق JetBrains بصيانته وترقيته بنشاط ، ولا تقلق بشأن شراء النسخة المدفوعة - إذا بدأت للتو مع Kotlin ، فإن إصدار المجتمع من IntelliJ سيخدم كل احتياجاتك. أهم ثلاثة جوانب في Kotlin أود أن أشير إليها هي: أ) موجز (يقلل بشكل كبير من الكود المعياري) ، ب) آمن (لسبب واحد ، فهو مصمم لتجنب استثناءات المؤشر الفارغ) ، و ج ) قابلة للتشغيل البيني (يمكنك الاستفادة من المكتبات الحالية لـ JVM أو Android أو المتصفح).
Kotlin Coroutines
الكل يريد الحصول على خدمات تخدم المستخدمين بسرعة. للوصول إلى أقصى سعة لخادمك ، فإن أول شيء يمكنك القيام به هو امتلاك تطبيق متعدد مؤشرات الترابط. جافا مرهقة للغاية مع ذلك. عندما تتعلم Java ، تتعلم أولاً أنه إذا كنت تريد تطبيقًا متعدد مؤشرات الترابط ، فيجب عليك إما توسيع فئة Thread أو تنفيذ واجهة Runnable. لا يفهم المبتدئون أبدًا ما هو الاختلاف (إذا كان هناك أي اختلاف) ، ولكن للإضافة إلى الارتباك ، يُطلب منهم أيضًا بدء سلسلة رسائل دائمًا باستخدام طريقة التشغيل ، وعدم استخدام طريقة البدء مطلقًا. أو انتظر ، هل كان العكس؟ بعد كل شيء ، لا يهم ، يجب ألا تبدأ مؤشر ترابط يدويًا على أي حال ، فهو مكلف للغاية ، بدلاً من استخدام تجمع مؤشرات الترابط. بسيط ، إلا أنه ليس كذلك.
لحسن الحظ ، لدى Kotlin حل أبسط يسمى coroutines. ببساطة ، تتيح coroutines إمكانية كتابة تعليمات برمجية غير متزامنة وغير معطلة بطريقة سلسة للغاية. الفكرة الأساسية هي وجود وظائف يمكن تعليقها ؛ بمعنى آخر ، يمكن تعليق الحساب في مرحلة ما واستئنافه لاحقًا. أفضل جزء هو أنه عند كتابة كود غير محظور ، فإن نموذج البرمجة لا يتغير حقًا ، لذا فإن كتابة كود غير محظور هو في الأساس نفس كتابة كود الحظر. دعونا نرى مثالين:
fun sendRequest(): Int { /* do some heavy work */ return 1; }
يوضح هذا المثال وظيفة الحظر. لن يقوم مؤشر الترابط الذي ينفذ مقتطف الشفرة هذا بأي عمل آخر حتى تعود الوظيفة ، والتي قد تستغرق بضع ثوانٍ في حالة وجود API أو استدعاء قاعدة البيانات. لا نريد حقًا حظر سلسلة الرسائل الخاصة بنا أثناء انتظار خدمة أخرى ، لذا دعنا نحول هذه الوظيفة إلى وظيفة غير محظورة.
suspend fun sendRequest(): Int { /* do some heavy work */ return 1; }
يوضح هذا المثال كيف يمكننا تحويل طريقتنا إلى وظيفة غير محظورة يمكن تعليقها. هذا يعني أنه ، من أجل التبسيط ، إذا كان العمل الشاق عبارة عن استدعاء وظيفة delay()
بسيط لمدة 10 ثوانٍ ، فإن سلسلة التنفيذ ستستمر في العمل على مهام أخرى في ذلك الوقت وستستأنف تنفيذ الوظيفة بعد مرور 10 ثوانٍ. رمز جميل غير محظور تم تحقيقه بكلمة رئيسية واحدة.
خدمة غير متزامنة مع Ktor
عندما يتعلق الأمر بكتابة واجهات برمجة تطبيقات REST ، فهناك بعض الخطوات الإضافية التي يجب على المرء اتخاذها ، مثل بدء تشغيل خادم مضمن أو تحليل الطلب ، وبالطبع لا أحد يريد القيام بذلك يدويًا. تحتوي Java على Spring Boot ، مما يجعل الأمور سهلة حقًا ، ولحسن الحظ ، فإن Kotlin لديها إطار عمل يسمى Ktor. Ktor هو إطار عمل ويب لبناء خوادم غير متزامنة. كما يوضح موقعه على الويب ، فإن Ktor "سهل الاستخدام وممتع وغير متزامن." الآن ، المتعة أمر شخصي ، لذلك لا أرغب في إثبات ذلك ، مع ذلك ، دعنا نرى مقتطفًا يثبت أنه سهل الاستخدام وغير متزامن.
fun main() { embeddedServer(Tomcat, 8080) { routing { get { call.respond("Hello world!") } } }.start(wait = true) }
يقدم المثال أعلاه خادم Kotlin Ktor يعمل بكامل طاقته ويعمل على خادم Tomcat مضمن ، ويستمع إلى المنفذ 8080 ، ويستجيب بشكل غير متزامن مع "Hello world!" للحصول على الطلبات. كل هذا في أقل من 10 أسطر من التعليمات البرمجية.
من الواضح أن كتور يمكنه فعل أكثر من ذلك بكثير. يتطلب تقديم جميع ميزات Ktor مقالته الخاصة ، ولكن من بين العديد من الأشياء ، فإنه يجعل تسجيل الدخول والمصادقة سهلاً مثل الفطيرة. اقرأ المزيد حول ما يمكن أن يفعله Ktor على جانب الخادم وكيفية تكوينه هنا.
الفوائد الأخرى لـ Kotlin في النهاية الخلفية
الفائدة الأولى التي أود أن أشير إليها هي أنه يمكنك استخدام مكتبات Java في Kotlin ، وثق بي ، هناك الكثير من مكتبات الجهات الخارجية المذهلة لجافا التي يمكن أن تجعل حياتك أسهل. لماذا تكتب التنفيذ الخاص بك عندما تكون هناك مكتبة مفتوحة المصدر وجاهزة للاستخدام تقوم بالمهمة على أكمل وجه؟ استخدام هذه مع Kotlin يعمل بشكل لا تشوبه شائبة.
ميزة أخرى رئيسية لـ Kotlin و Ktor هي مكتبات وأطر عمل الاختبار الشاملة التي يمكنك استخدامها. يعمل إطار عمل Junit مثل السحر مع Kotlin ، ويضيف Ktor علاوة على ذلك مكتبة الاختبار الخاصة به التي تسمح لك بكتابة الاختبارات الشاملة واختبارات التكامل في أي وقت من الأوقات. يمكنك استخدام محرك اختبار مخصص يقوم بتشغيل تطبيقك بالكامل ويمكنه التعامل مع الطلبات تمامًا كما يفعل التطبيق المباشر.
خاتمة
كما ذكرت سابقًا ، أنا في الأساس مطور Java للجهة الخلفية ولديها العديد من التطبيقات من جانب الخادم وواجهات برمجة تطبيقات REST ورائي. على الرغم من أنني أحب البرمجة في Java ، إلا أنني أعتقد أنه لا توجد لغة واحدة أو إطار عمل أفضل مثالي لأي وظيفة ويمكن أن يحل أي مشكلة. أسلوبي هو التعرف على أكبر عدد ممكن من الأدوات ، وعندما تظهر مشكلة ، اختر أفضل أداة يمكنها حل هذه المشكلة بالذات دون عيب.
كما يوضح موقع Kotlin ، لا يتمثل هدف Kotlin في أن تكون فريدًا ؛ بدلاً من ذلك ، فإنه يستمد الإلهام وأفضل الممارسات من عقود من تطوير اللغة ، وأعتقد أنه عندما يتعلق الأمر بالتطوير الخلفي ، فإن Kotlin و Coroutines و Ktor يصنعون ثلاثيًا رائعًا للقيام بهذه المهمة. يمكنك قراءة المزيد عن Kotlin وفائدتها كلغة برمجة هنا.