فهم واستخدام واجهات برمجة التطبيقات RESTful
Yi Sun
December 2, 2022
في عصر إنترنت الأشياء، هناك العديد من واجهات برمجة التطبيقات (APIs) المختلفة، ومن المهم توحيدها. تعد RESTful API واحدة من أكثر أنماط هندسة واجهات برمجة التطبيقات شيوعًا، والتي يمكن أن تساعدك على فصل اهتمامات جانب العميل عن جانب الخادم، مما يسمح للواجهة الأمامية والخلفية بالتطور بشكل منفصل وبالتالي تحسين الكفاءة. ميزة عدم الاحتفاظ بالحالة (stateless) يمكن أن تجعل التطبيق أكثر قابلية للتوسع وأسهل في تنفيذ سياسات التخزين المؤقت لتحسين تجربة المستخدم والأداء. في هذه المقالة، سنقدم ما هي RESTful API وكيف يمكننا استخدامها.
ما هي API
لنضع جانبًا للحظة ما هي API، ولنتحدث عن كيفية توصيل المعلومات في حياتنا.
عندما تأخذ أموالك إلى صاحب المتجر وتخبره أنك بحاجة إلى شراء بطاريات، يتلقى صاحب المتجر المال، ويجد البطاريات على الرف ويسلمها لك. يتم إتمام عملية شراء البطارية بنجاح.
من ناحية أخرى، تقوم برامج الكمبيوتر بإتمام هذا من خلال APIs. لنبدأ بتعريف ويكيبيديا:
واجهة برمجة التطبيقات (API) هي طريقة لتواصل برنامجين أو أكثر من برامج الكمبيوتر مع بعضهما البعض. إنها نوع من واجهة البرمجيات، تقدم خدمة لأجزاء أخرى من البرمجيات.
يقوم البرنامج A بطلب من البرنامج B من خلال API، ويقوم البرنامج B بإرجاع الاستجابة إلى A من خلال API بعد استعلامه عن موارده.
طلب البرنامج A من البرنامج B من خلال API يشبه إخبارك لصاحب المتجر أنك بحاجة إلى بطارية، وإرجاع البرنامج B للبيانات إلى البرنامج A يشبه قيام صاحب المتجر بالعثور على البطارية وتسليمها لك.
هذه العملية لا تتطلب من البرنامج B معرفة سبب رغبة البرنامج A في البيانات، تمامًا كما لن يسألك صاحب المتجر لماذا اشتريت البطارية. البرنامج A أيضًا لا يحتاج إلى معرفة كيف وجد البرنامج B البيانات، تمامًا كما لن تسأل صاحب المتجر من أين تم شراء البطاريات عند شرائك لها. كل برنامج يمرر المعلومات إلى الآخر من خلال APIs، وكل منهما يقوم بعمله الخاص، مما يجعل عالم البرمجة منظمًا وموثوقًا.
ما هي RESTful API
عرّف Roy Fielding REST (نقل الحالة التمثيلية) في أطروحة الدكتوراه الخاصة به عام 2000، "أنماط الهندسة وتصميم هندسة البرمجيات القائمة على الويب"، ويحدد نمط هندسة REST ستة قيود توجيهية. يُطلق على النظام الذي يتوافق مع بعض أو كل هذه القيود بشكل عام RESTful.
(المصدر: Seobility)
قيود RESTful APIs
القيود | التفاصيل | الفوائد |
---|---|---|
هندسة العميل-الخادم | تحسين قابلية نقل واجهة المستخدم عبر منصات متعددة من خلال فصل قضايا واجهة المستخدم عن قضايا تخزين البيانات، وتحسين قابلية التوسع من خلال تبسيط مكونات الخادم. | 1. فصل جانب العميل عن جانب الخادم. 2. تعزيز قابلية نقل منصات المستخدم عبر المنصات. 3. تعزيز قابلية توسع جانب الخادم. |
عدم الاحتفاظ بالحالة | يجب أن يحتوي كل طلب من العميل إلى الخادم على جميع المعلومات المطلوبة للطلب ولا يجب أن يستخدم أي سياق مخزن على الخادم، ويتم تخزين حالة الجلسة بالكامل على العميل. | 1. سهل التوسع، لا توجد تبعيات للجلسة وأي خادم يمكنه التعامل مع أي طلب. 2. سهل للتخزين المؤقت لتحسين أداء البرنامج. |
قابلية التخزين المؤقت | تتطلب أن يتم تمييز البيانات في الطلب أو الاستجابة بشكل ضمني أو صريح على أنها قابلة للتخزين المؤقت أو غير قابلة للتخزين المؤقت. إذا كان الاستجابة قابلة للتخزين المؤقت، فإنه يتم منح ذاكرة التخزين المؤقت للعميل الحق في إعادة استخدام بيانات الاستجابة هذه للطلبات المكافئة اللاحقة. | 1. تقليل عرض النطاق الترددي. 2. تقليل زمن الوصول. 3. تقليل حمل الخادم. 4. إخفاء حالة الشبكة. |
نظام الطبقات | يحدد سلوك المكونات المقيّدة مما يسمح للهندسة أن تتكون من طبقات بحيث لا يمكن لكل مكون "رؤية" ما وراء الطبقة المباشرة التي يتفاعل معها. من خلال تحديد معرفة النظام إلى طبقة واحدة، يتم تقليل تعقيد النظام بأكمله وتعزيز الاستقلالية في القاع. | 1. تقليل تعقيد النظام بأكمله. 2. تعزيز الاستقلالية في القاع. 3. يمكن تنفيذ موازنة الحمل بسهولة. 4. يمكن فصل منطق الأعمال وسياسات الأمان. |
الكود عند الطلب (اختياري) | يسمح بتمديد وظائف العميل من خلال تنزيل وتنفيذ الكود في شكل تطبيقات صغيرة أو نصوص برمجية. | 1. تحسين قابلية توسع النظام. |
واجهة موحدة | تحتوي على أربع نقاط رئيسية: 1. تحديد الموارد في الطلبات. يمكن للعملاء تحديد مورد من خلال URI الموجود في الطلب، وفصل مورد جانب الخادم عن المورد المطلوب من العميل. 2. معالجة الموارد من خلال التمثيلات. عندما يكون لدى العميل تمثيل لمورد، مثل URI، فإن هناك معلومات كافية لتعديل أو حذف المورد. 3. الرسائل الوصفية الذاتية. كل رسالة تتضمن معلومات كافية لإعلام العميل بما يجب فعله مع الرسالة. 4. الوسائط الفائقة كمحرك لحالة التطبيق (HATEOAS). لا يحتاج العميل إلى أي ترميز إضافي لجعل جميع الموارد متاحة للمستخدم عبر روابط الموارد التي يتم إرجاعها من الخادم. | 1. تبسيط هندسة النظام بأكمله. 2. تحسين وضوح التفاعلات. |
أفضل ممارسات RESTful API
التركيز على الواجهات الموحدة بين المكونات هو ميزة أساسية تميز نمط هندسة REST عن الأنماط الأخرى القائمة على الويب، وبناءً على هذه الميزة، تم فرز أفضل الممارسات هنا لمساعدتك على تصميم API الخاص بك بشكل أفضل.
تجنب الأفعال في اسم المسار
استخدم طرق HTTP للتعبير عن سلوك معالجة الموارد، بدلاً من تعريف أفعال السلوك في المسارات.
// جيد
curl -X GET http://httpbin.org/orders
// سيء
curl -X GET "http://httpbin.org/getOrders"
- الحصول على معلومات المورد لـ URI المحدد باستخدام GET
// يمثل الحصول على جميع معلومات الطلبات للنظام الحالي
curl -X GET http://httpbin.org/orders
// يمثل الحصول على معلومات تفاصيل الطلب لرقم الطلب 1
curl -X GET http://httpbin.org/orders/1
- إنشاء مورد من URI المحدد باستخدام POST
// يمثل إنشاء مورد باسم order
curl -X POST http://httpbin.org/orders \
-d '{"name": "awesome", region: "A"}' \
- إنشاء أو استبدال الموارد بالكامل على URI المحدد باستخدام PUT
// يمثل استبدال البيانات لطلب مع id 1
curl -X PUT http://httpbin.org/orders/1 \
-d '{"name": "new awesome", region: "B"}' \
- PATCH يقوم بتحديث جزئي للمورد
// يمثل تغيير حقل region للطلب مع id 1، مع الحفاظ على بقية البيانات دون تغيير
curl -X PATCH http://httpbin.org/orders/1 \
-d '{region: "B"}' \
- إزالة مورد من خلال تحديد URI باستخدام DELETE
// يمثل حذف الطلب مع id 1
curl -X DELETE http://httpbin.org/orders/1
استخدام صيغة الجمع في URIs
إذا كنت ترغب في استخدام صيغة المفرد للإشارة إلى الوصول إلى نوع معين من الموارد:
curl -X GET "http://httpbin.org/order"
استخدام صيغة المفرد قد يربك المستخدم بأن هناك طلب واحد فقط في النظام، ولكن استخدام صيغة الجمع سيجعل الفهم أكثر سلاسة.
curl -X GET "http://httpbin.org/orders"
الاستفادة الجيدة من رموز حالة HTTP
يحدد معيار HTTP رموز الحالة، والتي يمكن تصنيفها على نطاق واسع إلى الفئات التالية:
رموز الحالة | المعنى |
---|---|
2xx | نجاح، تم استلام العملية ومعالجتها بنجاح |
3xx | إعادة توجيه، مطلوب إجراء إضافي لإكمال الطلب |
4xx | خطأ العميل، يحتوي الطلب على خطأ في الصيغة أو لا يمكن إكمال الطلب |
5xx | خطأ الخادم، حدث خطأ أثناء معالجة الخادم للطلب |
باستخدام رموز الحالة القياسية، يمكن للمطورين تحديد المشكلات على الفور ويمكن تقليل الوقت المستغرق للعثور على أنواع مختلفة من الأخطاء.
التحكم في الإصدار
مع تغير متطلبات الأعمال، من المرجح أن تحتاج واجهات برمجة التطبيقات التي تم نشرها بالفعل إلى التعديل وفقًا لذلك. إذا كانت واجهات برمجة التطبيقات الخاصة بنا تستخدم من قبل أطراف ثالثة، فمن الواضح أنه لا يمكننا جعل كل عميل يتغير وفقًا لتغيرات واجهات برمجة التطبيقات الخاصة بنا، لذا فقد حان الوقت لإدخال مفهوم إدارة إصدار API، والذي يمكن أن يضمن الاستخدام الطبيعي لواجهات برمجة التطبيقات التاريخية وتكرار واجهات برمجة التطبيقات الجديدة لتلبية متطلبات الأعمال الجديدة.
الوسائل الشائعة للتحكم في الإصدار هي:
- التحكم في الإصدار من خلال المسارات في الطلبات
// طلب API v1
curl http://httpbin.org/v1/orders
// طلب API v2
curl http://httpbin.org/v2/orders
- التحكم في الإصدار من خلال معلمات الاستعلام
// طلب API v1
curl http://httpbin.org/orders?version=v1
// طلب API v2
curl http://httpbin.org/v2/orders?version=v2
- التحكم في الإصدار من خلال الرأس
// طلب API v1
curl http://httpbin.org/orders -H "custom-version: v1"
// طلب API v2
curl http://httpbin.org/orders -H "custom-version: v2"
كيف تعزز APISIX RESTful API
Apache APISIX هي بوابة API ديناميكية وفورية وعالية الأداء. يمكنها العمل أمام أي خدمة RESTful API واستخدام الإضافات لإضافة خدمات جديدة وتوسيع وظائفها، وهو ما يتوافق مع تعريف RESTful لنظام الطبقات. بالإضافة إلى ذلك، بالنسبة لبعض الخدمات التاريخية التي لا تتبع تعريف RESTful API، يمكن لـ APISIX أيضًا مساعدتك في تحويل واجهتك دون تغيير كود الأعمال الأصلي بحيث تفي واجهتك بقيود REST الخاصة بالواجهة الموحدة، مما يجعل API الخاص بك يتوافق بشكل أفضل مع مواصفات RESTful API.
نظام الطبقات: يدعم فصل منطق الأعمال ومنطق الأمان
يمكنك التركيز فقط على تنفيذ منطق الأعمال، ويمكن ترك منطق أمان الواجهة لإضافات APISIX من فئة المصادقة، مثل key-auth. تدعم APISIX عددًا كبيرًا من إضافات المصادقة، لنأخذ openid-connect كمثال، كما هو موضح في الشكل التالي:
يمكننا أن نرى أن استخدام APISIX (بوابة API) لإضافة طبقة من منطق المصادقة أمام خادم الأعمال الخاص بنا يمكن أن يعمل على حماية الخدمات العلوية، وهذا النمط الهندسي يمكن أن يكون طريقة جيدة لفصل منطق الأعمال عن منطق الأمان.
نظام الطبقات: دعم بروتوكولات موازنة الحمل المتعددة
يمكن إعداد APISIX، كبوابة API، بين جانب العميل والخادم لتلبية متطلبات موازنة الحمل المختلفة. يمكنك حتى تخصيص منطق موازنة الحمل.
الخوارزميات المدعومة لموازنة الحمل هي:
roundrobin
: موازنة الحمل بالتناوب مع الأوزان.chash
: التجزئة المتسقة.ewma
: اختيار العقدة ذات أقل زمن وصول. انظر رسم EWMA لمزيد من التفاصيل.least_conn
: اختيار العقدة ذات أقل قيمة لـ(active_conn + 1) / weight
. هنا، الاتصال النشط هو الاتصال الذي يتم استخدامه من قبل الطلب وهو مشابه لمفهوم في Nginx.- موازن حمل مخصص يتم تحميله عبر
require("apisix.balancer.your_balancer")
الواجهة الموحدة: جعل واجهات API التاريخية أكثر توافقًا مع RESTful
بالنسبة لواجهات API التاريخية التي كانت موجودة لفترة طويلة ولا تتبع إرشادات RESTful API بشكل جيد، يمكنك إعادة تغليف API الجديدة من خلال APISIX لتلبية سيناريوهات الأعمال المختلفة دون تعديل منطق API الأصلي.
- استخدام proxy-rewrite لإعادة كتابة طلبات العميل
كما ذكرنا أعلاه، لا يجب أن يكون هناك أفعال في مسارنا.
على سبيل المثال، إذا كانت واجهة API التاريخية تحتوي على واجهة /getOrder
، فيمكننا توجيه طلب API إلى واجهة API التاريخية من خلال إضافة proxy-rewrite.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/orders",
"plugins": {
"proxy-rewrite": {
"uri": "/getOrder",
"scheme": "http",
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
يمكنك أيضًا استخدام الإضافة لعمليات إصدار API.
- استخدام إضافة response-rewrite لإعادة كتابة استجابات الخادم
عندما تكون واجهة API التاريخية تحتوي على رموز حالة استجابة غير قياسية، يمكننا استخدام response-rewrite لتوجيه الاستجابة لتعديل رمز حالة الاستجابة.
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/orders",
"plugins": {
"response-rewrite": {
"status_code": 201,
"body": "{\"code\":\"ok\",\"message\":\"new json body\"}",
"vars":[
[ "status","==",200 ]
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:80": 1
}
}
}'
يمثل المثال أعلاه طلبًا لتعديل حالة 200 إلى 201 في API التي تطلب مسار /orders.
نظرًا لأن APISIX تدعم إضافات غنية جدًا، أنا أتطلع إلى استكشافك المزيد من الطرق للعب.
الخلاصة
تقدم هذه المقالة ما هي API، وما هي RESTful API، وأفضل ممارساتها. بالإضافة إلى ذلك، تقدم المقالة أيضًا كيفية فصل منطق الأعمال ومنطق الأمان من خلال APISIX، وكيفية استخدام APISIX لجعل خدمات API التاريخية أكثر توافقًا مع RESTful دون تغيير كود الأعمال الأصلي. نأمل أن تساعدك هذه المقالة على فهم RESTful APIs.