تحديد معدل طلبات API
تحدّ وقتي عدد طلبات API التي يمكن لكل مستأجر إرسالها خلال نافذة زمنية منزلقة. تحمي الحدود استقرار المنصة وتضمن استخدامًا عادلًا بين العملاء.
نظرة عامة
يُطبَّق تحديد المعدل لكل رمز API (وبالتالي ضمن سياق المستأجر). عند إرسال طلب، يُحتسب ضمن:
- الحدّ في الدقيقة (burst) — عدد الطلبات المسموح به خلال نافذة قصيرة.
- الحصة اليومية — إجمالي الطلبات المسموح بها في اليوم التقويمي (UTC)، باستثناء Enterprise حيث لا يُفرض سقف يومي.
إذا تجاوزت أيًا من الحدّين، تُرجع API الاستجابة 429 Too Many Requests. تتضمن الاستجابات الناجحة ترويسات يمكنك من خلالها خفض سرعة العميل قبل الوصول للحد.
عنوان الأساس (كما في مرجع API الرئيسي):
https://api.waqti.sa/v1حدود المعدل حسب الخطة
تعتمد الحدود على اشتراكك. الخطط الأعلى تسمح بمزيد من الإنتاجية للتكاملات والتقارير والأتمتة.
| الخطة | طلبات / دقيقة | طلبات / يوم |
|---|---|---|
| Basic | 60 | 1,000 |
| Professional | 300 | 10,000 |
| Enterprise | 1,000 | غير محدود |
تغيير الخطة
عند الترقية أو التخفيض، تُطبَّق الحدود الجديدة مع أول طلب بعد انتشار تحديث الفوترة (عادة خلال دقائق قليلة).
ترويسات الاستجابة
تتضمن كل استجابة API ترويسات قياسية لحد المعدل حتى تتمكن العملاء من الإبطاء بشكل استباقي.
| الترويسة | الوصف |
|---|---|
X-RateLimit-Limit | أقصى عدد طلبات مسموح به في نافذة الدقيقة الحالية لخطتك. |
X-RateLimit-Remaining | العدد التقريبي للطلبات المتبقية في نافذة الدقيقة الحالية. |
X-RateLimit-Reset | الطابع الزمني Unix (بالثواني) عند إعادة ضبط نافذة الدقيقة. |
مثال (استجابة ناجحة):
HTTP/1.1 200 OK
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 1705312260
Content-Type: application/jsonعند بلوغ حد الدقيقة، تكون قيمة X-RateLimit-Remaining مساوية لـ 0 وقد تشير Retry-After إلى عدد الثواني قبل إعادة المحاولة (انظر أدناه).
429 Too Many Requests
عند تجاوز حد الدقيقة أو الحد اليومي، تُرجع API الاستجابة 429 مع جسم JSON وترويسات مفيدة.
مثال للاستجابة
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705312305
Content-Type: application/json{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please retry after 45 seconds."
},
"meta": {
"timestamp": "2025-01-15T10:31:45Z",
"request_id": "req_rl_9f3a2b1c"
}
}| الترويسة / الحقل | الغرض |
|---|---|
Retry-After | الثواني للانتظار قبل إعادة المحاولة (نافذة الدقيقة). |
X-RateLimit-Reset | وقت إعادة ضبط نافذة الدقيقة (Unix بالثواني). |
error.code | سبب قابل للقراءة آلياً (RATE_LIMIT_EXCEEDED). |
مثال لطلب قد يؤدي إلى 429
curl -i -X GET "https://api.waqti.sa/v1/purchase-orders" \
-H "Authorization: Bearer 3|a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0" \
-H "Accept: application/json"عند التقييد، تكون حالة الاستجابة 429 ويوضح الجسم الشرط. عند استنفاد الحصة اليومية، تعكس الرسالة السقف اليومي؛ استخدم X-RateLimit-Reset (عند وجوده) أو تفاصيل الخطأ details لمعرفة بداية اليوم التالي بتوقيت UTC.
أفضل الممارسات
التراجع الأسي (Exponential backoff)
عند 429، لا تعيد المحاولة فورًا في حلقة ضيقة. استخدم تراجعًا أسيًا مع عشوائية طفيفة (jitter):
- اقرأ
Retry-After(بالثواني) عند توفرها وانتظر على الأقل هذه المدة. - وإلا ابدأ بتأخير قصير (مثل 1 ثانية)، واضاعف عند تكرار 429، مع سقف (مثل 60 ثانية).
- أضف عشوائية طفيفة حتى لا تعيد عدة عمال المحاولة في نفس اللحظة.
التخزين المؤقت (Caching)
- خزّن بيانات مرجعية مستقرة (الموردون، الأقسام، الإعدادات) حيث يسمح تكاملك بذلك.
- استخدم طلبات مشروطة أو ETag /
If-None-Matchعند دعم API لذلك لتجنب إعادة تنزيل الموارد دون تغيير. - فضّل استدعاءات قائمة واحدة مع مرشحات (
search،status، نطاقات التواريخ) بدل العديد من استدعاءات التفاصيل الصغيرة عند المزامنة.
سير العمل القائم على الدُفعات
- فضّل الترقيم (pagination) مع
per_pageمعقول (حتى الحد الأقصى الموثّق) بدل ضرب API بصفحات صغيرة جدًا. - سلسل عمليات الكتابة التي تعتمد على بعضها؛ تضاعف الكتابات المتوازية الحمل وأنماط الفشل.
- جدول التقارير الثقيلة أو إعادة الملء (backfills) خارج أوقات الذروة عند الإمكان.
نقاط نهاية القراءة مقابل الكتابة
تنطبق نفس حصص الدقيقة واليوم على كل حركة API المصادق عليها. ما يختلف هو كيفية استخدام نقاط نهاية القراءة مقابل الكتابة:
| الفئة | طرق HTTP | نقاط نهاية نموذجية | ملاحظات التكامل |
|---|---|---|---|
| قراءة | GET (وHEAD عند الدعم) | قوائم وعرض الموارد (/purchase-orders، /vendors/{id}، …) | آمن لإعادة المحاولة؛ مناسب للتخزين المؤقت والترقيم. |
| كتابة | POST، PUT، PATCH، DELETE | إنشاء/تحديث/حذف، إرسال للموافقة، إلخ | استخدم مفاتيح idempotency عند توفرها؛ تجنب الإرسال المكرر عند إعادة المحاولة بعد انتهاء المهلة. |
الاحتساب: يُحتسب طلب HTTP واحد ضمن حدودك سواء كان قراءة أو كتابة. غالبًا تثير عمليات الكتابة المزيد من العمل الخلفي (التحقق، سير العمل)، لذا اجعل نِسَب burst للكتابة أقل من نظيرها النظري للقراءة حتى عند تساوي الحد الرقمي.