توفر الكثير من المواقع واجهات برمجية Application Programming Interface ،API بهدف إتاحة موارد الموقع لتطبيقات خارجية؛ قد تكون تطبيقات ٍللجوال، أجهزةً لوحية، أو أجهزةً مكتبية. قد نود مثلا إنشاء تطبيق للجوال نعرض فيه منتجات الموقع. نستخدم لغة البرمجة المناسبة للتطبيق (جافا مثلا لتطبيقات أندرويد) الذي يرسل طلبات لواجهتنا البرمجية يحصُل بموجبها على بيانات يتولى هو طريقة عرضها. نقول إن تطبيق الجوال في هذه الحالة يستهلك Consume الواجهة البرمجية.
هذا الدرس جزء من سلسلة تعلم Laravel والتي تنتهج مبدأ "أفضل وسيلة للتعلم هي الممارسة"، حيث ستكون ممارستنا عبارة عن إنشاء تطبيق ويب للتسوق مع ميزة سلة المشتريات. يتكون فهرس السلسلة من التالي:
- مدخل إلى Laravel 5.
- تثبيت Laravel وإعداده على كلّ من Windows وUbuntu.
- أساسيات بناء تطبيق باستخدام Laravel.
- إنشاء روابط محسنة لمحركات البحث (SEO) في إطار عمل Laravel.
- نظام Blade للقوالب.
- تهجير قواعد البيانات في Laravel.
- استخدام Eloquent ORM لإدخال البيانات في قاعدة البيانات، تحديثها أو حذفها.
- إنشاء سلة مشتريات في Laravel.
- الاستيثاق في Laravel.
- إنشاء واجهة لبرمجة التطبيقات API في Laravel. (هذا الدرس)
- إنشاء مدوّنة باستخدام Laravel.
- استخدام AngularJS واجهةً أمامية Front end لتطبيق Laravel.
- الدوّال المساعدة المخصّصة في Laravel.
- استخدام مكتبة Faker في تطبيق Laravel لتوليد بيانات وهمية قصدَ الاختبار.
نغطي في هذا الدرس المواضيع التالية:
- ماهي واجهات REST البرمجية؟
- الممارسات المنصوح بها في واجهات REST البرمجية.
- إنشاء واجهة برمجية لمشروع Larashop.
ماهي واجهات REST البرمجية؟
توصف الكثير من الواجهات البرمجية بأنها RESTful، فما المقصود بهذا الوصف؟
تختصر REST العبارة Representational State Transition (النقل التمثيلي للحالة) وهي طريقة لتصميم البرمجيات تعرِّف معاييرَ يجب على خدمات الويب اتباعها من أجل أداء أعلى وصيانة أسهل. تعتمد بنية التطبيقات REST على بروتوكول HTTP لإرسال الطلبات والحصول على إجابات؛ ومن أهم القيود التي يجب الالتزام بها في تطبيقات REST: العمل حسب مبدأ خادوم-عميل Server-Client، انعدام الحالة Stateless وتوحيد الواجهات (إضافة لقيود أخرى).
- مبدأ خادوم-عميل: يجب التفريق بين واجهة المستخدم والخادوم الذي يخزن البيانات ويطبق العمليات عليها.
- انعدام الحالة: يجب أن يحوي الطلب الموجّه من العميل إلى الخادوم كل المعلومات الضرورية ليستطيع الخادوم فهمه والإجابة عليه؛ دون الحاجة لسياق محفوظ على الخادوم (لفهم الطلب).
- توحيد الواجهات بمعنى أن كل مورد على الخادوم يمكن تعريفه فرديا واستغلاله عبر بيانات تمثله يحتفظ بها العميل. يجب أن تكون الطلبات واضحة يمكن فهمها والإجابة عنها دون الحاجة لمعلومات خارجة عنها. يدخل ضمن توحيد الواجهات أيضا افتراضُ العميل أن أي إجراء Action غيرُ متوفر على الخادوم، ما لم يصّرح هذا الأخير بتوفره.
تساهم هذه القيود (والقيود الأخرى التي تعرفها بنية REST) في تسهيل عمل الواجهات، الرفع من أدائها، تيسير الصيانة وقابلية التمدد Scalability. سنرى في الفقرة التالية توصيات لبناء واجهات برمجية تساعد في احترام مبادئ REST.
ملحوظة: يكثُر وصف الواجهات البرمجية بأنها RESTful (تلتزم بقيود REST) دون أن تلتزم بكامل القيود التي تعرِّفها بنية REST، وهو ما يجعلها أقرب لواجهات شبيهة لـREST منها لواجهات RESTful.
الممارسات المنصوح بها في واجهات REST البرمجية
يُساعد الالتزام بالممارسات التالية في بناء واجهة تطبيقات برمجية ذات أداء عال وقابلية كبيرة للتمدد والصيانة.
- استخدام إجراءات HTTP لتحديد العمل الذي سيؤديه الخادوم: GET للحصول على مورد، POST لإنشاء مورد جديد، PUT لتحديث مورد وDELETE لحذفه.
- أَصْدَرَة Versioning الواجهة: يساعد استخدام إصدارات في عدم كسر التطبيقات التي تستهلك الواجهة البرمجية. يحدّد العميل إصدار واجهة التطبيق الذي يود العمل عليه مما يسمح بإحداث تغييرات على الخادوم تضمَّن في إصدار جديد دون أن يتوقف عملاء الواجهة البرمجية.
- من المتعارف عليه استخدام أسماء جموع لوصف الموارد،
api.mysite/v1/products
مثلا للمنتجات. ليس واجبا اتباع هذا العرف لكن الأهم هو تناسق تسمية الموارد: لا تخلط بين أسماء مفردة للموارد وجموع. - استخدام الإجابات الجزئية: طلب العميل اسم المنتج؟ أرسل اسم المنتج فقط، وليس كامل بيانات المنتج، في الإجابة.
- استخدام رموز الحالة: تسهّل رموز الحالة في HTTP التخاطب مع العميل. عولج الطلب على النحو الأمثل؟ أرسِل الرمز
200
في الإجابة. طلب العميل إنشاء مورد وتم الأمر؟ أرسل الرمز201
في الإجابة؛ وهكذا. راجع هذا الرابط للمزيد من رموز الحالة في HTTP. - ضع حدًّا أقصى لعدد الطلبات القادمة من نفس عنوان IP في الواجهات المفتوحة للجميع. يساعد هذا الأمر في التصدي للعملاء الذي يفرطون في استخدام واجهة تطبيقاتك البرمجية. ينصح أيضا بحظر عناوين IP ذات السلوك المشبوه حتى لا يؤثر على بقية المستخدمين.
- قد يُختلف حول هذه التوصية، إلا أنه يُنصح باستخدام صيغة
JSON
لإرسال البيانات في الإجابة عن الطلب، ما لم يحدّد العميل عكس ذلك. - خبِّئ Cache نتائج طلبات
GET
التي لا تتغير كثيرا. ربما تكون قائمة العلامات التجارية في مواقع التسوق مثالا جيدا للبيانات التي يجب تخبئتها (قد تمضي أشهر دون الحاجة لإضافة علامة تجارية جديدة).
واجهة Larashop البرمجية
سننشئ في هذه الفقرة واجهة تطبيقات برمجية لمشروع Larashop. تشتمل الواجهة على المسارات أدناه. تستخدم جميع المسارات إجراء GET
للحصول على المورد.
التسلسل | المورد | الرابط | الوصف | رمز الحالة |
---|---|---|---|---|
1 | Product | /api/v1/products | سرد لائحة بالمنتجات وخاصياتها | 200 |
2 | Product | /api/v1/products/1 | سرد خاصيات المنتج رقم 1 | 200 |
3 | Category | /api/v1/categories | سرد لائحة بتصنيفات المنتجات | 200 |
4 | Category | /api/v1/categories/1 | التصنيف ذو المعرّف 1 | 200 |
لاحظ أننا لم نتح إمكانية التعديل على الموارد عبر الواجهة. تشير v1
في المسارات إلى رقم الإصدار 1
.
نفتح ملف المسارات routes.php
ونعدّله بإضافة المسارات التالية:
// API routes... Route::get('/api/v1/products/{id?}', ['middleware' => 'auth.basic', function($id = null) { if ($id == null) { $products = App\Product::all(array('id', 'name', 'price')); } else { $products = App\Product::find($id, array('id', 'name', 'price')); } return Response::json(array( 'error' => false, 'products' => $products, 'status_code' => 200 )); }]); Route::get('/api/v1/categories/{id?}', ['middleware' => 'auth.basic', function($id = null) { if ($id == null) { $categories = App\Category::all(array('id', 'name')); } else { $categories = App\Category::find($id, array('id', 'name')); } return Response::json(array( 'error' => false, 'user' => $categories, 'status_code' => 200 )); }]);
يعرف المسار
Route::get('/api/v1/products/{id?}', ['middleware' => 'auth.basic', function($id = null)
رابطًا يطلب المنتجات مع معرّف اختياري id
. يُستخدم المعرف لطلب منتج واحد وفي حال عدم ذكره ترجِع واجهة التطبيقات جميع المنتجات. نحمي المورد بالتعليمة 'middleware' => 'auth.basic'
التي تستوثق من العميل. حددنا نمط الاستيثاق بـauth.basic
لاستخدام بريد المستخدِم (حقل email
في جدول users
) مع كلمة السر.
يستدعي كل مسار النموذج المناسب للعثور على البيانات في القاعدة ثم نرسل الإجابة بصيغة JSON
بالتعليمة Response::json
.
عند طلب الرابط http://larashop.dev/api/v1/products
ستظهر نافذة تطلب إدخال بريد المستخدم وكلمة سره.
استخدم الحساب الذي أنشأته في درس الاستيثاق وستظهر النتيجة التالية في المتصفح (بعد التنسيق)
{ "error":false, "products": [ { "id":"1", "name":"Mini skirt black edition", "price":"35" }, { "id":"2", "name":"T-shirt blue edition", "price":"64" }, { "id":"3", "name":"Sleeveless Colorblock Scuba", "price":"13" } ], "status_code":200 }
حصلنا على إجابة بصيغة JSON
للطلب الذي أرسلناه من أجل الحصول على منتجات الموقع. يشير الرمز 200
إلى أن معالجة الطلب تمّت دون مشاكل. يمكن للعميل الآن تنسيق الإجابة لعرضها بطريقة مناسبة.
خاتمة
وضعنا في هذا الدرس أساسا يمكن البناء عليه لإنشاء واجهات برمجية أكثر تطورا. يتلخص إنشاء واجهات برمجية في Laravel في تعريف المسارات، استخدام النماذج للحصول على البيانات المطلوبة ثم تهيئة الإجابة بصيغة JSON
ثم إرسالها.
ترجمة -وبتصرّف- للمقال Laravel 5 REST API لصاحبه Rodrick Kazembe.
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.