مبادئ REST API — REST APIs
مبادئ REST API
الـ API عقد بين الواجهة (أو تطبيق جوال، أو خدمة أخرى) والخادم. REST أسلوب لتصميم هذا العقد فوق HTTP بحيث يكون متوقعاً ومتسقاً.
الموارد والعناوين
كل شيء مورد (كتب، مستخدمون، طلبات) له عنوان. العنوان اسم بالجمع لا فعل:
| ✅ | ❌ |
|---|---|
| GET /books | GET /getAllBooks |
| POST /books | POST /createBook |
| DELETE /books/42 | GET /deleteBook?id=42 |
الفعل تحدده طريقة HTTP.
الطرق
| الطريقة | المعنى | آمنة؟ | متكررة بلا أثر إضافي (idempotent)؟ |
|---|---|---|---|
| GET | قراءة | ✅ | ✅ |
| POST | إنشاء (أو إجراء) | ❌ | ❌ — طلبان = موردان |
| PUT | استبدال كامل | ❌ | ✅ |
| PATCH | تعديل جزئي | ❌ | غالباً لا |
| DELETE | حذف | ❌ | ✅ |
- آمنة: لا تغيّر شيئاً. لذلك GET يجب ألا يحذف أو يعدّل أبداً (المتصفحات ومحركات البحث تطلب روابط GET تلقائياً).
- Idempotent: تكرار الطلب لا يغيّر النتيجة بعد المرة الأولى — مهم عند إعادة المحاولة بعد انقطاع الشبكة.
رموز الحالة
| الرمز | المعنى | متى |
|---|---|---|
| 200 OK | نجاح | GET، PUT، PATCH |
| 201 Created | أُنشئ | POST (مع المورد الجديد) |
| 204 No Content | نجاح بلا جسم | DELETE |
| 400 Bad Request | مدخلات غير صالحة | فشل التحقق |
| 401 Unauthorized | غير مسجل (لا هوية) | لا رمز أو رمز منتهٍ |
| 403 Forbidden | مسجل لكن غير مسموح | ليس المالك |
| 404 Not Found | غير موجود | |
| 409 Conflict | تعارض | بريد مستخدم مسبقاً |
| 422 Unprocessable | صيغة صحيحة ومعنى خاطئ | بعض الفرق تفضله للتحقق |
| 429 Too Many Requests | تجاوز الحد | Rate limiting |
| 500 Internal Error | خطأ في الخادم | لا تكشف التفاصيل للعميل |
الرمز الصحيح يسمح للعميل بالتصرف آلياً: 401 ← اطلب تسجيل الدخول، 429 ← انتظر وأعد.
عدم حفظ الحالة (Stateless)
كل طلب يحمل كل ما يحتاجه الخادم لفهمه (مثل رمز الدخول). الخادم لا يتذكر "الطلب السابق". هذا يسمح بتشغيل عدة نسخ من الخادم خلف موزع حمل.
شكل البيانات
- JSON بأسماء حقول متسقة (createdAt أو created_at — اختر واحداً).
- أخطاء بصيغة موحدة: { "error": { "code": "VALIDATION_ERROR", "message": "...", "details": [...] } }.
- تواريخ بصيغة ISO 8601: "2026-10-01T12:00:00Z".
تمرين
صمّم (على الورق) API لمكتبة: الموارد، العناوين، الطرق، رموز الحالة لكل حالة نجاح وفشل، بما فيها: استعارة كتاب مُعار مسبقاً (أي رمز؟).
// مثال على تصميم REST API جيد
const express = require('express');
const app = express();
app.use(express.json());
// ===== GET - جلب الموارد =====
// جلب كل المستخدمين
app.get('/api/users', (req, res) => {
res.json({ success: true, data: users });
});
// جلب مستخدم واحد
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'المستخدم غير موجود'
});
}
res.json({ success: true, data: user });
});
// ===== POST - إنشاء مورد =====
app.post('/api/users', (req, res) => {
const newUser = {
id: generateId(),
...req.body,
createdAt: new Date()
};
users.push(newUser);
res.status(201).json({ success: true, data: newUser });
});
// ===== PUT - تحديث كامل =====
app.put('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === req.params.id);
if (index === -1) {
return res.status(404).json({ success: false, error: 'Not found' });
}
users[index] = { id: req.params.id, ...req.body };
res.json({ success: true, data: users[index] });
});
// ===== DELETE - حذف =====
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === req.params.id);
if (index === -1) {
return res.status(404).json({ success: false, error: 'Not found' });
}
users.splice(index, 1);
res.status(204).send();
});اختبر فهمك