كيف تبني RESTful API باستخدام إطار البايثون Django
restful web services شرح :
restful web services شرح : أهلًا وسهلًا بكم في هذا المقال الجديد الذي سنتناول فيه موضوعًا جديدًا من مواضيع لغة البرمجة بايثون وهو موضوع بناء واجهة برمجية RESTful API باستخدام إطار عمل جانغو Django.
من المهم في البداية التعرف على مفهوم RESTful API، وسنتطرق بشكل مختصر إلى أهم الأُطر البرمجية في البايثون والتي يمكنك من خلالها بناء واجهة برمجية، وسنقدم لكم تطبيقًا عمليًا وشرح وافي حول هذا الموضوع.
ما هي RESTful API؟
تُعتبر REST (اختصارًا لـ REpresentational State Transfer) معيارًا خاصا لبناء خدمات الويب والواجهات البرمجية API الخاصة بالويب، ويتم استخدامها من قبل تطبيقات ويب أو موبايل وحتى تطبيقات سطح المكتب، ولنكون دقيقين أكثر، فإن أي برنامج أو نظام يمتلك الإمكانية للتعامل مع بروتوكول HTTP ووظائفه فهو مخول لاستخدام ,والتعامل مع Restful API.
REST is essentially a set of useful conventions for structuring a web API
خصائص RESTful API
لابد لأي نظام RESTful الالتزام ببعض القيود والشروط التي تُعطيه صفة REST وهذه بعضها:
- نظام خادم-عميل: لابد من وجود فصل بين مُقدم الخدمة (Server) وبين المُستهلك الذي يستخدم الخدمة (Client).
- عدمية متابعة الحالة (Stateless): لابد لكل طلب (Request) يتم ارساله الى الخادم أن يحتوي على كافة المعلومات اللازمة لتنفيذ الطلب، ولا يمكن للخادم الاحتفاظ بأي بيانات تخص طلب مُعين لاستخدامها في تنفيذ طلب أخر.
- التخبئة (Cacheable): لابد للخادم من إعلام الجهة الطالبة للطلب بإمكانية تخبئة الطلبات أم لا.
- نظام الطبقات: لابد من بناء الإتصال بين الخادم والعميل بطريقة معيارية بحيث لو تطلب وجود طرف ثالث بين الخادم والعميل لتنفيذ الطلبات عوضًا عن الخادم ألا يحتاج العميل أن يقوم بشيء مختلف.
تم تصميم هيكلية REST لكي توائم بروتوكول HTTP، ويُعتبر “المصدر (Resource)” هو اللب الأساسي لـ Restful API ويتم تمثيل المصدر بمُعرف المورد النظامي (URI)، ويقوم العميل بإرسال الطلبات لهذه URIs باستخدام أحد وظائف بروتوكول HTTP وقد ينتج عن ذلك تغيير في المصدر الذي استقبل الطلب.
وظائف خدمات RESTful API
يُمكنك من خلال خدمات RESTful من تطوير نظام ويب يحتوي على كافة العمليات الأساسية للتعامل مع البيانات وهو ما نُطلق عليه عمليات CURD اختصارًا لـ (CREATE، UPDATE، RETRIEVE، DELETE) ويُمكننا الحصول على ذلك من خلال استخدام وظائف HTTP الأساسية التالية:
- GET: لجلب بيانات.
- POST: لإنشاء أو إضافة بيانات جديدة.
- PUT: لتعديل أو استبدال بيانات.
- DELETE: لحذف بيانات.
يوجد وظائف أخرى مثل OPTION، PATCH، CONNECT، TRACE ولها استخداماتها الخاصة.
أشهر أطر البايثون التي تتيح بناء RESTful API
لا يخفى على أحد قوة لغة البايثون في مجال الويب، والأُطر المختصة بالويب في البايثون كثيرة والرابط التالي يُفصل هذه الأطر مع شرح لكل إطار:
https://wiki.python.org/moin/WebFrameworks
من أشهر أُطر الويب الموجودة في البايثون والتي تُقدم إمكانية بناء خدمات وواجهات RESTful هو إطار Django والذي يُسهل من عملية بناء الخدمات والواجهات عبر كتابة شيفرة برمجية قليلة، بالإضافة لإطار Flask الشهير.
سنتناول في شرحنا في هذا المقال كيفية بناء واجهة برمجية RESTful باستخدام اطار العمل Django.
الجانب العملي
سوف نبدأ العمل ببناء واجهة برمجية RESTful باستخدام اطار Django ومكتبة Django REST Framework وستقوم هذه الواجهة بإجراء عمليات CRUD على قاعدة بيانات بسيطة من نوع SQLite.
نظام التشغيل المُستخدم في هذا المقال هو Windows 10 64 bit.
تنبيه مهم: ما سنقوم به في هذا المقال هو مثال، ولن يكون كافيًا لأن تستخدم الخطوات الموجودة فيه لبناء واجهة برمجية Restful في بيئة عملية حقيقية.
يوجد طريقتان رئيسيتان في بناء الواجهة البرمجية RESTful في إطار العمل Django وهما:
- Function Based : عند طلب أي واجهة Restful في هذا النوع، فإنه يتم تنفيذ دالة أو وظيفة مُعينة، وهذا النوع كان الأشهر سابقًا وهو ما سنتحدث عنه لسهولته في الشرح والتوضيح.
- Class Based : في هذا النوع يتم التعامل مع فئات (Classes) وليس دوال، وهو الذي يُنصح به وسنحاول أن نُفرد له مقالا خاصا.
تصميم واجهات برمجية خاصة ببيانات طلاب
سنفترض أننا نريد بناء واجهات برمجية للتعامل مع بيانات طلاب، وستكون هذه البيانات محفوظة في جدول بإسم Students في قاعدة بيانات SQLite بالأعمدة التالية:
- Student_Name (اسم الطالب)
- Student_College (الكلية)
- Student_Avg (المعدل)
- Admission_Date (تاريخ القبول)
الجدول التالي يوضح الوظائف الأربعة الرئيسية في RESTful API الخاصة بالطلاب والواجهات البرمجية التي سنبنيها:
[spbtbl_sc id=4]
تثبيت إطار العمل والمكتبات اللازمة
لتثبيت إطار العمل Django نقوم بتنفيذ الأمر التالي في الطرفية:
سنحتاج لتثبيت المكتبة الخاصة بواجهات RESTful والتي تُسمى Django REST Framework ولذلك نقوم بتنفيذ الأمر التالي:
لاحظ أن اسم المكتبة طويل ومن كلمة واحدة.
ملاحظة/ يُفضل أن تقوم باستخدام أداة virtualenv أثناء العمل، وتستطيع الإطلاع على بعض تفاصيل هذه الأداة في هذا مقال أداة virtualenv كأداة لتسهيل البرمجة والعمل بلغة البايثون
بناء المشروع ومجلد العمل
بعد أن قمنا بتثبيت الإطار والمكتبة اللازمة للعمل، نقوم بتنفيذ الأمر التالي في مسار العمل الذي نريده:
الأمر السابق سينشئ مجلد جديد في مسار العمل الحالي باسم students_api وهذا المجلد يُمثل مجلد المشروع ويحتوي على ملفات بايثون متعددة.
نقوم بالدخول في المجلد، ومن ثم نقوم بتنفيذ الأمر التالي:
الأمر السابق يقوم بإنشاء مجلد جديد باسم students داخل مجلد students_api، وهذا المجلد الجديد يُمثل التطبيق الذي سنقوم ببناء الواجهات البرمجية داخله.
يحتوي مجلد students على ملفات بايثون بالإضافة لمجلد باسم migrations والذي سيحتوي على ملفات خاصة بتهجير قاعدة البيانات.
قم بفتح الملف settings.py الموجود داخل المجلد students_api الداخلي (وليس الرئيسي) وقم بإضافة ‘rest_framework’ و ‘students.app.StudentsConfig’ الى المصفوفة INSTALLED_APPS الموجودة في الملف لتصبح كالتالي:
بذلك نكون أضفنا التطبيق students الى المشروع الرئيسي students_api.
إنشاء النماذج (Models)
يحتوي ملف models.py الموجود في مجلد students على الفئات التي تُمثل الجداول في قاعدة البيانات، ومن خلال هذا الملف نستطيع إنشاء الجداول في قاعدة البيانات والتعديل على هيكليتها وإعداداتها.
سنقوم بإنشاء فئة باسم Students (ترث من الفئة models.Model) وسنحدد خصائص هذه الفئة.
خصائص الفئة هنا تُمثل أعمدة جدول students.
قم بفتح ملف models.py واكتب الشيفرة التالية ثم احفظه:
قمنا خلال الشيفرة السابقة بإنشاء فئة باسم Students وعرفنا داخلها الخصائص التي تمثل أعمدة الجدول في قاعدة البيانات. تمثل ordering خيارًا لجعل النتائج مُرتبة ترتيبًا تصاعديا عند جلبها.
بعد أن قمنا بتجهيز النموذج الخاص بجدول الطلاب، نحتاج للقيام بخطوة خاصة لبناء ملف التهجير لقاعدة البيانات، وسيحتوي ملف التهجير على الشيفرة البرمجية اللازمة لبناء قاعدة البيانات والجدول وكل ما يلزم.
لإنشاء ملف التهجير نُنفذ الأمر التالي:
بعد تنفيذ الأمر السابق، سيتم إنشاء ملف التهجير باسم 0001_initial.py داخل مجلد migrations.
لتنفيذ عملية التهجير وبناء قاعدة البيانات وجدول بيانات الطلاب، نُنفذ الأمر التالي:
الأمر السابق سيقوم بإنشاء قاعدة البيانات باسم db.sqlite3 في المجلد الرئيسي students_api وسينشئ الجدول بداخلها بالإضافة لمجموعة أخرى من الجداول والتي ستلزم في العمل مستقبلا.
تستطيع استكشاف قاعدة البيانات db.sqlite3 من خلال استخدام البرنامج SQLite Browser والذي تستطيع الحصول عليه من الموقع التالي : http://sqlitebrowser.org
قد يتبادر الى ذهنك كيف تم تحديد نوع قاعدة البيانات SQLite؟ وماذا لو أردت أن أستخدم نوعًا أخرًا من قواعد البيانات؟
الإجابة تكمن في ملف settings.py والذي يحتوي على إعدادات قاعدة البيانات المرتبطة بالمشروع والموجودة في المتغير DATABASES والذي يأخذ قيمة تلقائية كالتالي:
طبيعة وشكل البيانات
عندما نتحدث عن الوجهات البرمجية RESTful فإننا نتكلم (من جهة معينة) عن طرفين يتم انتقال البيانات بينهما، لذلك، فإن موضوع شكل البيانات وهيئتها من المواضيع المهمة في هذا الأمر، فكيف من الممكن أن نتفق على هيئة واحدة يستطيع كل طرف التعامل معها؟ الإجابة على ذلك هو استخدام ونقل البيانات على شكل بيانات JSON، وهو ما سنتكلم عنه فيما يلي.
لابد على الواجهات البرمجية التي سنبنيها أن تكون قادرة على إجراء عمليات Serialization و Deserialization لبيانات الطلاب الموجودة على هيئة JSON، لذلك سنقوم ببناء وسيط (Mediator) بين العناصر (Instances) من فئة الطلاب، وبين المتغيرات الأولية للبايثون (Primitives). هذا الوسيط عبارة عن فئة ترث خصائصها من الفئة serializers.Serializer.
سنقوم بإنشاء ملف جديد باسم serializers.py في مجلد students، وسنكتب بداخله الشيفرة التالية:
الفئة StudentsSerializer هي الوسيط الذي تكلمنا عنه، ويجب أن يحتوي على البيانات التي سيتم تحويلها من/الى JSON، وبالإضافة لذلك، يجب أن يتم عمل implementation للوظائف create و update الموروثة من الفئة serializers.Serializer بالشكل الموضح في الشيفرة.
الواجهات البرمجية RESTful API
يتم كتابة الشيفرة البرمجية الخاصة بالواجهات في ملف views.py داخل مجلد students.
قم بفتح الملف واحفظ بداخله الشيفرة التالية:
الشيفرة السابقة تُمثل الواجهات البرمجية التي سيتم تنفيذها عند طلبها من قبل العميل او المستهلك، وتحتوي بشكل رئيسي على ثلاثة عناصر رئيسية هي الفئة JSONResponse ووظيفتين students_list و student_detail.
الفئة JSONResponse عبارة عن Response ولكن من نوع JSON، وهذه الفئة ترث خصائصها من الفئة HttpResponse ولقد قمنا بإنشائها لحاجتنا أن يكون محتوى رد الطلبات على هيئة بيانات JSON وليس على شكل نصي مثلا.
الوظيفة students_list هي الواجهة الأولى والتي تقوم بمهمتين عند ورود الطلب.
المهمة الأولى في حالة كان نوع الطلب GET سيتم إرجاع بيانات كافة الطلاب.
المهمة الثانية في حالة كان نوع الطلب POST سيتم استخراج بيانات الطالب الجديدة من الطلب عبر إجراء عملية Parsing للطلب ومن ثم حفظ هذه البيانات في قاعدة البيانات بعد التأكد من سلامتها.
الوظيفة student_detail تقوم بتنفيذ ثلاث مهمات حسب نوع الطلب، ففي حالة كان الطلب GET يتم إرجاع بيانات طالب مُحدد حسب رقم pk الخاص به، وإذا كان الطلب من نوع PUT فسيتم تحديث أو تعديل بيانات طالب وفق البيانات المرفقة مع الطلب ووفق رقم pk الخاص بالطالب.
وفي حالة كان نوع الطلب DELETE فسيتم حذف بيانات طالب مُحدد وفق رقم pk المرفق مع الطلب.
من المهم قبل تنفيذ الإجراءات السابقة التأكد من وجود الطالب في قاعدة البيانات، وهو ما تم عمله في بداية الوظيفة، ففي حالة عدم وجود طالب وفق رقم pk المرفق، فسيتم إرجاع رد يحتوي على كود الحالة 404 الدال على عدم وجود البيانات المطلوبة.
إضافة روابط RESTful API
الأن وبعد أن قمنا بكتابة الشيفرة الخاصة بالواجهات البرمجية، يجب علينا أن نقوم بإنشاء ملف urls.py داخل مجلد students.
وظيفة هذا الملف هو تعريف روابط الواجهات البرمجية عبر استخدام تعبيرات Regular Expression وربطها بالوظائف التي تمثل الواجهات البرمجية.
قم بإنشاء الملف urls.py وقم بوضع الشيفرة البرمجية التالية فيه وأحفظه:
يجب علينا تعديل ملف urls.py الموجود في المجلد students_api بحيث يتم تعريف root url والتي ستحتوي على مجموعة الروابط المُعرفة مُسبقا في ملف urls.py السابق الموجود في مجلد students.
قم بفتح الملف urls.py الموجود في المجلد students_api وعدله ليصبح كالتالي:
تشغيل RESTful API وتجريبها
الان نستطيع تشغيل الخادم الخاص بالواجهات البرمجية (الغير امنة بعد) وتجريبه عبر تنفيذ الأمر التالي:
إذا كان كل ما قمنا به صحيحا ودون وجود أخطاء، وبعد تنفيذ الأمر السابق، سنحصل على نتيجة مشابهة لما يلي:
System check identified no issues (0 silenced).
January 27, 2018 – 11:15:57
Django version 2.0, using settings ‘students_api.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
الان يوجد عدة خيارات لإختبار الواجهات البرمجية التي أعددناها، حيث يمكننا استخدام أدوات وبرامج جاهزة لذلك، فمثلًا، نستطيع استخدام أداة curl أو httpie (مكتبة بايثون) في الطرفية لإرسال طلبات للواجهات البرمجية واستقبال الرد ورؤية النتيجة.
الأمر التالي يقوم بإرسال طلب من نوع GET للواجهة البرمجية الأولى students_list باستخدام أداة httpie. وسيقوم هذا الطلب بإرجاع بيانات كافة الطلاب الموجودين في قاعدة البيانات:
وبما أنه لا يوجد بيانات لدينا، فستكون النتيجة بالشكل التالي:
الأمر التالي يقوم بإرسال طلب من نوع POST للواجهة البرمجية students_list والتي ستقوم بحفظ البيانات المرفقة مع الطلب في جدول الطلاب بعد التأكد من صحتها:
سيكون ناتج الأمر السابق كالتالي:
قد يكون التعامل مع هكذا أدوات صعبًا للبعض نوعًا ما، لذلك فإنه من الممكن استخدام أدوات أخرى ذات واجهات رسومية وسهلة الاستخدام مثل برنامج Postman.
خاتمة
خلال هذا المقال تعرفنا على كيفية بناء واجهة برمجية RESTful API من خلال استخدام الإطار البرمجي الخاص بالويب في لغة البايثون والمُسمى Django، وكما ذكرت خلال هذا المقال، فإن الخطوات الموجودة فيه هدفها التمهيد وشرح طريقة البدء بكتابة الواجهات البرمجية بالبايثون، وبالطبع يوجد إعدادات أخرى لتأمين الواجهات وكتابتها بطريقة متقدمة.
الشيفرة البرمجية في هذا المقال وبعض النقاط مأخوذة بتصرف عن الباب الأول في كتاب Building RESTful Python Web Services للمؤلف Gastón C. Hillar وهذا هو رابط الكتاب على موقع أمازون:
مرحبا
حابه اسال في الكتابة استخدمة فقط موجة الاوامر او محرر اكواد اخر ؟