كيفية تصميم واجهات REST API ذاتية التكرار ومُدارة الإصدارات
تنشر ميزة جديدة، وفجأة تتلقى واجهة API الخاصة بك طلبات POST مكررة من العملاء الذين يعيدون المحاولة بعد انتهاء المهلة. تحتوي قاعدة بياناتك الآن على طلبين متطابقين. أو تُطلق تغييرًا كاسرًا، فتنهار تطبيقات الجوال لأنها كانت تتوقع تنسيق الاستجابة القديم. هاتان مشكلتان من أكثر المشكلات شيوعًا وإيلامًا في تصميم API: العمليات غير ذاتية التكرار والتغييرات الكاسرة. يوضح لك هذا الدليل كيفية حل كلتيهما باستخدام أنماط عملية للتكرار الذاتي وإدارة الإصدارات في واجهات REST API.
لماذا يهم التكرار الذاتي في واجهات REST API
التكرار الذاتي يعني أن إرسال الطلب نفسه عدة مرات له نفس تأثير إرساله مرة واحدة. لطرق HTTP دلالات محددة للتكرار الذاتي: GET وHEAD وPUT وDELETE وOPTIONS ذاتية التكرار، بينما POST وPATCH ليست كذلك. لكن واجهات API الواقعية غالبًا ما تحتاج إلى قبول POST لعمليات مثل إنشاء الموارد أو معالجة المدفوعات. يمكن أن تؤدي أعطال الشبكة ومهلات انتهاء صلاحية العميل ومنطق إعادة المحاولة إلى حدوث تكرارات. بدون التكرار الذاتي، تخاطر بالخصم المزدوج أو السجلات المكررة أو حالة غير متسقة.
تقنيات لواجهات REST API ذاتية التكرار
1. استخدم مفاتيح التكرار الذاتي لطلبات POST
النهج الأكثر شيوعًا هو السماح للعملاء بإرسال مفتاح فريد (مثل UUID) في ترويسة Idempotency-Key. يخزّن الخادم المفتاح ونتيجة العملية. إذا تم استقبال المفتاح نفسه مرة أخرى، يعيد الخادم النتيجة المخزنة بدلاً من إعادة تنفيذ العملية.
POST /payments
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{
"amount": 1000,
"currency": "USD"
}
خطوات التنفيذ:
- يولّد العميل مفتاحًا فريدًا (UUID v4) لكل عملية منطقية.
- يتحقق الخادم مما إذا كان المفتاح موجودًا في مخزن دائم (مثل Redis أو قاعدة بيانات).
- إذا لم يكن موجودًا، يعالج الطلب ويخزّن المفتاح مع حالة الاستجابة ونصها.
- إذا كان موجودًا، يعيد الاستجابة المخزنة دون إعادة المعالجة.
اضبط انتهاء صلاحية معقولاً (مثل 24 ساعة) لتجنب نمو التخزين غير المحدود.
2. استفد من الطلبات الشرطية
للتحديثات، استخدم ترويسات ETag وIf-Match لمنع فقدان التحديثات. يعيد الخادم ETag يمثل الحالة الحالية. يرسله العميل مرة أخرى مع If-Match؛ إذا تغيّر المورد، يعيد الخادم 412 Precondition Failed. هذا يجعل طلبات PUT آمنة ضد حالات التسابق.
PUT /articles/123
If-Match: "abc123"
Content-Type: application/json
{"title": "Updated title"}
3. صمّم PUT للتكرار الذاتي الطبيعي
فضّل PUT على POST عندما يمكن للعميل تحديد عنوان URL للمورد. على سبيل المثال، PUT /users/{userId} ذاتي التكرار بطبيعته لأن الاستدعاءات المتكررة تستبدل المورد نفسه. استخدم POST فقط عندما يعيّن الخادم المعرّف.
4. تعامل مع اكتشاف التكرار باستخدام القيود الفريدة
اجمع مفاتيح التكرار الذاتي مع قيود قاعدة البيانات الفريدة على المفاتيح التجارية (مثل رقم الطلب). إذا تسرب تكرار، ترفضه قاعدة البيانات، ويمكنك إرجاع 409 Conflict مع رسالة واضحة.
استراتيجيات إدارة الإصدارات لواجهات REST API
تتطور واجهات API. الحقول الجديدة أو السلوك المتغير أو نقاط النهاية المحذوفة يمكن أن تكسر العملاء الحاليين. تتيح لك إدارة الإصدارات إدخال تغييرات دون تعطيلهم. هناك عدة استراتيجيات شائعة:
| الاستراتيجية | مثال | المزايا | العيوب |
|---|---|---|---|
| مسار URI | /v1/users |
صريح، سهل التوجيه، مناسب للتخزين المؤقت | تتغير عناوين URL، قد يسبب الفوضى |
| معامل الاستعلام | /users?version=1 |
بسيط، اختياري | سهل الإغفال، ليس RESTful |
| ترويسة مخصصة | Accept-Version: v1 |
يحافظ على نظافة عناوين URL | أصعب في الاختبار عبر المتصفح |
| نوع الوسائط | Accept: application/vnd.api.v1+json |
تفاوض المحتوى، REST خالص | معقد، أقل شيوعًا |
لمعظم الفرق، إدارة إصدارات مسار URI هي الخيار الأكثر عملية. إنها مرئية وسهلة التوثيق وتعمل جيدًا مع بوابات API وشبكات CDN.
كيفية إدارة الإصدارات دون كسر العملاء
- ابدأ بـ v1 في المسار من اليوم الأول. إضافة إدارة الإصدارات لاحقًا أصعب.
- تغييرات إضافية فقط ضمن إصدار واحد: حقول اختيارية جديدة، نقاط نهاية جديدة. لا تحذف أو تعدّل أسماء الحقول أبدًا.
- أوقف الدعم بلطف: أعلن عن نهاية العمر، وقدم أدلة الترحيل، وراقب استخدام الإصدارات القديمة.
- استخدم ترويسات sunset:
Sunset: Sat, 31 Dec 2025 23:59:59 GMTلإبلاغ العملاء. - حافظ على إصدارين نشطين كحد أقصى لتقليل عبء الصيانة.
جمع كل شيء معًا: مثال عملي
خذ بعين الاعتبار واجهة API للمدفوعات. تريد إنشاء دفعة بشكل ذاتي التكرار وإدارة إصدار نقطة النهاية.
POST /v1/payments
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{
"amount": 1000,
"currency": "USD"
}
منطق الخادم:
- تحقق مما إذا كان
Idempotency-Keyموجودًا في Redis. - إذا كان موجودًا، أعد الاستجابة المخزنة مؤقتًا (الحالة + النص).
- إذا لم يكن موجودًا، عالج الدفعة، وخزّن المفتاح مع الاستجابة، وأعد 201 Created.
للتحديثات، استخدم PUT مع ETag:
PUT /v1/payments/123
If-Match: "xyz789"
Content-Type: application/json
{"amount": 1500}
إذا لم يتطابق ETag، أعد 412. هذا يمنع استبدال التغييرات المتزامنة.
المزالق الشائعة وكيفية تجنبها
- تخزين مفاتيح التكرار الذاتي إلى الأبد: اضبط TTL (مثل 24 ساعة) لتجنب تضخم التخزين.
- تجاهل حالات التسابق: استخدم عمليات ذرية (مثل Redis SETNX) للتحقق من المفاتيح وتعيينها.
- إدارة الإصدارات متأخرًا جدًا: أضف /v1 من البداية.
- تغييرات كاسرة في الإصدارات الثانوية: تعامل مع أي تغيير يعدّل بنية الاستجابة كتغيير رئيسي.
- عدم توثيق التكرار الذاتي: حدد بوضوح نقاط النهاية التي تدعم Idempotency-Key.
الأسئلة الشائعة
ما هي واجهة REST API ذاتية التكرار؟
تضمن واجهة REST API ذاتية التكرار أن إرسال الطلب نفسه عدة مرات ينتج نفس النتيجة كإرساله مرة واحدة. هذا أمر بالغ الأهمية للتعامل مع إعادة المحاولات بأمان، خاصة للطرق غير ذاتية التكرار مثل POST.
أي طرق HTTP ذاتية التكرار؟
GET وHEAD وPUT وDELETE وOPTIONS وTRACE ذاتية التكرار. POST وPATCH ليست ذاتية التكرار افتراضيًا، لكن يمكنك جعلها كذلك باستخدام تقنيات مثل مفاتيح التكرار الذاتي.
ما هي أفضل طريقة لإدارة إصدارات REST API؟
إدارة إصدارات مسار URI (مثل /v1/users) هي النهج الأكثر شيوعًا وعملية. إنها صريحة وسهلة التوجيه وتعمل جيدًا مع التخزين المؤقت وبوابات API. تشمل الخيارات الأخرى معاملات الاستعلام والترويسات المخصصة وأنواع الوسائط، لكن لها مقايضات.
هل أنت مستعد لاختبار استجابات JSON لواجهة API الخاصة بك؟ استخدم JSON Formatter للتحقق من الحمولات وتنسيقها بسرعة.