مبادئ تصميم واجهة البرمجة وأفضل الممارسات
لماذا يهم تصميم واجهة البرمجة
واجهة برمجة مصممة بشكل جيد مثل مكتبة منظمة بشكل جيد. يمكن للمستخدمين العثور على ما يحتاجون إليه بسرعة، وفهم كيفية استخدامه بشكل بديهي، والشعور بالثقة في أنه لن يتغير بشكل غير متوقع. التصميم السيئ لواجهة البرمجة يؤدي إلى الارتباك والإحباط وكوابيس الصيانة.
هيكل URL: الأساس
عناوين URL هي نقاط الدخول إلى واجهتك البرمجية. يجب أن تكون بديهية ومتسقة ويمكن التنبؤ بها. فكر في عناوين URL كجدول محتويات لواجهتك البرمجية.
المبادئ الأساسية:
1. استخدم الأسماء، وليس الأفعال
يجب أن تمثل عناوين URL الموارد (الأسماء)، وليس الإجراءات (الأفعال). يشير أسلوب HTTP إلى الإجراء.
❌ سيء - أفعال في عناوين URL:
GET /api/getUsers
POST /api/createUser
POST /api/updateUser/123
POST /api/deleteUser/123
✅ جيد - أسماء مع أساليب HTTP:
GET /api/users // الحصول على جميع المستخدمين
POST /api/users // إنشاء مستخدم
PUT /api/users/123 // تحديث مستخدم
DELETE /api/users/123 // حذف مستخدم
2. استخدم الأسماء بصيغة الجمع للمجموعات
يجب أن تستخدم المجموعات دائماً أسماء بصيغة الجمع للحفاظ على الاتساق، حتى عند إرجاع عنصر واحد.
❌ سيء - مفرد/جمع غير متسق:
GET /api/user/123 // مستخدم واحد
GET /api/users // مستخدمون متعددون
GET /api/product/456 // منتج واحد
GET /api/products // منتجات متعددة
✅ جيد - دائماً صيغة الجمع:
GET /api/users/123 // مستخدم واحد
GET /api/users // مستخدمون متعددون
GET /api/products/456 // منتج واحد
GET /api/products // منتجات متعددة
3. الهيكل الهرمي للعلاقات
استخدم عناوين URL المتداخلة لتمثيل العلاقات بين الموارد.
// منشورات المستخدم
GET /api/users/123/posts
// منشور محدد لمستخدم
GET /api/users/123/posts/456
// التعليقات على منشور
GET /api/posts/456/comments
// تعليق محدد
GET /api/posts/456/comments/789
// متداخل ثلاثة مستويات (تجنب عموماً التداخل الأعمق)
GET /api/users/123/posts/456/comments
4. استخدم الأحرف الصغيرة والشرطات
يجب أن تكون عناوين URL بأحرف صغيرة مع شرطات تفصل الكلمات، وليس الشرطات السفلية أو camelCase.
❌ سيء:
/api/UserProfiles
/api/user_profiles
/api/userProfiles
✅ جيد:
/api/user-profiles
5. لا تستخدم امتدادات الملفات
تستخدم واجهات البرمجة الحديثة رؤوس Content-Type، وليس امتدادات الملفات.
❌ سيء:
GET /api/users.json
GET /api/users.xml
✅ جيد:
GET /api/users
Accept: application/json
اصطلاحات تسمية الموارد
التسمية المتسقة تجعل واجهتك البرمجية قابلة للتنبؤ وسهلة التعلم.
أنماط الموارد القياسية:
| النمط | الغرض | مثال |
|---|---|---|
| /resources | مجموعة من الموارد | /users, /products, /orders |
| /resources/:id | مورد محدد | /users/123, /products/abc |
| /resources/:id/subresources | مجموعة متداخلة | /users/123/posts |
| /resources/actions | عمليات غير CRUD | /users/search, /orders/export |
تسمية نقاط النهاية الخاصة:
// البحث والتصفية
GET /api/users/search?q=أحمد
GET /api/products?category=electronics&price_max=1000
// العمليات الدفعية
POST /api/users/batch-create
POST /api/products/batch-update
DELETE /api/users/batch-delete
// الإجراءات التي لا تناسب CRUD
POST /api/users/123/activate
POST /api/orders/456/cancel
POST /api/invoices/789/send
// التجميعات والإحصائيات
GET /api/users/count
GET /api/sales/statistics
GET /api/reports/summary
// المصادقة والتفويض
POST /api/auth/login
POST /api/auth/logout
POST /api/auth/refresh
GET /api/auth/me
إصدار واجهة البرمجة: التخطيط للتغيير
ستتطور واجهتك البرمجية. يسمح لك الإصدار بإجراء تغييرات دون كسر العملاء الحاليين.
استراتيجيات الإصدار:
1. إصدار مسار URL (موصى به)
الأكثر شيوعاً ووضوحاً. الإصدار هو جزء من مسار URL.
GET /api/v1/users
GET /api/v2/users
المزايا:
✅ واضح ومرئي
✅ سهل توجيه إصدارات مختلفة
✅ بسيط للتنفيذ
✅ يعمل مع جميع عملاء HTTP
العيوب:
❌ تتغير عناوين URL بين الإصدارات
❌ يمكن أن يؤدي إلى ازدواجية الكود
2. إصدار معامل الاستعلام
يتم تحديد الإصدار كمعامل استعلام.
GET /api/users?version=1
GET /api/users?version=2
المزايا:
✅ عنوان URL الأساسي يبقى كما هو
✅ سهل الافتراض إلى أحدث إصدار
العيوب:
❌ أقل وضوحاً
❌ يمكن نسيانه في الطلبات
❌ أصعب للتخزين المؤقت
3. إصدار الرأس
يتم تحديد الإصدار في رأس مخصص أو رأس Accept.
GET /api/users
X-API-Version: 1
أو
GET /api/users
Accept: application/vnd.myapi.v1+json
المزايا:
✅ عناوين URL نظيفة
✅ يتبع مبادئ REST (التفاوض على المحتوى)
العيوب:
❌ غير مرئي في عناوين URL
❌ أصعب للاختبار (حاجة لتعيين الرؤوس)
❌ أكثر تعقيداً للتنفيذ
4. إصدار النطاق الفرعي
يتم تحديد الإصدار كنطاق فرعي.
GET https://api-v1.example.com/users
GET https://api-v2.example.com/users
المزايا:
✅ عزل كامل بين الإصدارات
✅ سهل نشر الإصدارات بشكل منفصل
العيوب:
❌ يتطلب إدارة DNS
❌ تعقيد شهادة SSL
❌ مزيد من النفقات العامة للبنية التحتية
أفضل ممارسات الإصدار:
- ابدأ بـ v1: لا تنتظر واجهة البرمجة "المثالية". أطلق v1 وكرر.
- استخدم إصدارات صحيحة: v1, v2, v3 (وليس v1.1, v1.2)
- حافظ على الإصدارات القديمة: امنح العملاء وقتاً للترحيل (6-12 شهراً)
- وثق الإهمال: وضح بوضوح متى ستنتهي الإصدارات
- أضف رؤوس الإهمال: حذر العملاء بشأن نقاط النهاية المهملة
// تحذير الإهمال في رؤوس الاستجابة
HTTP/1.1 200 OK
Deprecation: true
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
Link: <https://api.example.com/v2/users>; rel="successor-version"
{
"data": [...],
"meta": {
"deprecation_warning": "سيتم إزالة نقطة النهاية هذه في 31 ديسمبر 2026. قم بالترحيل إلى v2."
}
}
معاملات الاستعلام: التصفية والفرز والترقيم
تعمل معاملات الاستعلام على توسيع قدرات واجهتك البرمجية دون تشويش عناوين URL.
التصفية:
// فلتر واحد
GET /api/users?status=active
// فلاتر متعددة
GET /api/users?status=active&role=admin
// فلاتر النطاق
GET /api/products?price_min=10&price_max=100
GET /api/posts?created_after=2026-01-01
// مطابقة جزئية
GET /api/users?name_contains=أحمد
GET /api/products?sku_starts_with=ABC
// قيم متعددة (مفصولة بفواصل أو معامل متكرر)
GET /api/users?roles=admin,editor
GET /api/users?role=admin&role=editor
الفرز:
// فرز بسيط
GET /api/users?sort=name
// ترتيب تنازلي (بادئة بعلامة ناقص)
GET /api/users?sort=-created_at
// حقول فرز متعددة
GET /api/users?sort=role,-created_at
// بناء جملة بديل
GET /api/users?sort_by=name&order=asc
الترقيم:
ضروري لمجموعات البيانات الكبيرة. توجد أساليب متعددة:
ترقيم قائم على الإزاحة:
GET /api/users?page=1&limit=20
GET /api/users?offset=0&limit=20
الاستجابة:
{
"data": [...],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 150,
"total_pages": 8,
"links": {
"first": "/api/users?page=1",
"prev": null,
"next": "/api/users?page=2",
"last": "/api/users?page=8"
}
}
}
ترقيم قائم على المؤشر (أفضل لمجموعات البيانات الكبيرة):
GET /api/users?cursor=abc123&limit=20
الاستجابة:
{
"data": [...],
"pagination": {
"next_cursor": "xyz789",
"prev_cursor": "abc123",
"has_more": true
}
}
المزايا:
✅ نتائج متسقة (لا تكرارات/تخطيات)
✅ أداء أفضل على مجموعات البيانات الكبيرة
✅ يعمل بشكل جيد مع البيانات في الوقت الفعلي
اختيار الحقل (مجموعات الحقول المتناثرة):
دع العملاء يطلبون فقط الحقول التي يحتاجون إليها.
// تحديد حقول محددة
GET /api/users?fields=id,name,email
// استبعاد الحقول
GET /api/users?fields=-password,-ssn
// الحقول المتداخلة
GET /api/users?fields=id,name,profile.avatar
توسيع العلاقات:
تضمين الموارد ذات الصلة في طلب واحد.
// الاستجابة الافتراضية (بدون توسيع)
GET /api/posts/123
{
"id": 123,
"title": "منشوري",
"author_id": 456
}
// العلاقات الموسعة
GET /api/posts/123?expand=author,comments
{
"id": 123,
"title": "منشوري",
"author": {
"id": 456,
"name": "أحمد محمد"
},
"comments": [
{"id": 1, "text": "منشور رائع!"}
]
}
الاتساق: القاعدة الذهبية
الاتساق أكثر أهمية من الكمال. بمجرد إنشاء الأنماط، التزم بها في جميع أنحاء واجهتك البرمجية.
مجالات للحفاظ على الاتساق:
- اصطلاحات التسمية: camelCase مقابل snake_case (اختر واحداً)
- تنسيقات التاريخ: ISO 8601 (2026-02-14T10:30:00Z)
- تنسيق استجابة الخطأ: نفس الهيكل في كل مكان
- نمط الترقيم: لا تخلط بين ترقيم الإزاحة والمؤشر
- القيم المنطقية: true/false، وليس 1/0 أو yes/no
- معالجة null: تضمين حقول null أو حذفها (اختر واحداً)
// هيكل استجابة متسق
{
"data": {...}, // بيانات المورد الفعلية
"meta": {...}, // البيانات الوصفية (الترقيم، العدادات)
"links": {...} // روابط الوسائط الفائقة
}
// هيكل خطأ متسق
{
"error": {
"code": "VALIDATION_ERROR",
"message": "فشل التحقق",
"details": [
{
"field": "email",
"message": "البريد الإلكتروني مطلوب"
}
]
}
}
أمثلة واجهات برمجة واقعية
دعنا ننظر إلى كيفية هيكلة الشركات الرائدة لواجهات البرمجة الخاصة بها:
واجهة برمجة GitHub:
GET /repos/{owner}/{repo}
GET /repos/{owner}/{repo}/issues
GET /repos/{owner}/{repo}/issues/{number}
GET /repos/{owner}/{repo}/pulls
GET /user/repos?sort=updated&direction=desc
الميزات:
✅ هيكل هرمي واضح
✅ إصدار مسار URL (/v3/)
✅ تصفية شاملة
✅ ترقيم المؤشر للمجموعات الكبيرة
واجهة برمجة Stripe:
GET /v1/customers
POST /v1/customers
GET /v1/customers/{id}
GET /v1/customers/{id}/subscriptions
GET /v1/charges?limit=10
الميزات:
✅ عناوين URL بسيطة وقابلة للتنبؤ
✅ إصدار بادئة (/v1/)
✅ تسمية معامل متسقة
✅ موارد قابلة للتوسيع
واجهة برمجة Twitter:
GET /2/tweets/{id}
GET /2/users/{id}/tweets
GET /2/tweets/search/recent?query=api
الميزات:
✅ إصدار في المسار (/2/)
✅ تصميم يركز على الموارد
✅ بحث قائم على الاستعلام
✅ رؤوس حد المعدل
صمم نقاط نهاية واجهة برمجة REST لنظام مدونة بسيط مع هذه المتطلبات:
- يمكن للمستخدمين إنشاء وقراءة وتحديث وحذف منشورات المدونة
- يمكن أن تحتوي المنشورات على تعليقات متعددة
- يمكن تصفية المنشورات حسب الفئة والمؤلف
- يمكن ترقيم التعليقات
- يمكن للمستخدمين إعجاب المنشورات
صمم نقاط النهاية هذه:
- الحصول على جميع المنشورات: _________________
- إنشاء منشور جديد: _________________
- الحصول على منشور محدد: _________________
- تحديث منشور: _________________
- حذف منشور: _________________
- الحصول على تعليقات لمنشور: _________________
- إضافة تعليق إلى منشور: _________________
- إعجاب منشور: _________________
- الحصول على منشورات حسب المؤلف: _________________
- الحصول على منشورات مع الترقيم: _________________
إجابات عينة:
- GET /api/v1/posts
- POST /api/v1/posts
- GET /api/v1/posts/{id}
- PUT /api/v1/posts/{id} أو PATCH /api/v1/posts/{id}
- DELETE /api/v1/posts/{id}
- GET /api/v1/posts/{id}/comments
- POST /api/v1/posts/{id}/comments
- POST /api/v1/posts/{id}/likes
- GET /api/v1/posts?author_id=123
- GET /api/v1/posts?page=1&limit=20
النقاط الرئيسية
- استخدم الأسماء في عناوين URL، وليس الأفعال - دع أساليب HTTP تحدد الإجراءات
- استخدم دائماً أسماء الجمع للمجموعات للحفاظ على الاتساق
- احتفظ بعناوين URL الهرمية لكن تجنب التداخل لأكثر من 2-3 مستويات
- استخدم أحرفاً صغيرة مع شرطات في عناوين URL
- قم بإصدار واجهتك البرمجية من اليوم الأول (إصدار مسار URL موصى به)
- وفر التصفية والفرز والترقيم من خلال معاملات الاستعلام
- الاتساق أكثر أهمية من الكمال
- ادرس واجهات البرمجة الناجحة (GitHub، Stripe، Twitter) واعتمد أنماطها
- وثق كل شيء - التصميم الجيد ليس بديهياً بدون توثيق