الأخطاء وحدود الطلبات في واجهة مُجيب البرمجية
حدود الطلبات في واجهة مُجيب البرمجية 60 طلبًا في الدقيقة لكل مفتاح، وكل خطأ يعود بالشكل نفسه: رمز HTTP وجسم JSON فيه code ثابت وmessage يشرحه. هذه الصفحة تجمع الرموز كلها، وما تفعله عند كل منها، وكيف تبقى داخل الحد.
كيف يبدو الخطأ في الواجهة؟
رابط القسم «كيف يبدو الخطأ في الواجهة؟»كل خطأ جسمه كائن واحد اسمه error، فيه الحقلان code وmessage:
{ "error": { "code": "NOT_FOUND", "message": "Contact not found" } }codeرمز ثابت بحروف إنجليزية كبيرة. ابنِ برنامجك عليه.messageشرح بالإنجليزية للمطوّر، وقد يتغيّر نصه، فلا تبنِ عليه شيئًا.issuesو**issueCount** يظهران فقط مع الخطأ 400 عندما يكون معامل في الرابط غير صالح:issuesقائمة بأول 20 مشكلة وُجدت، كل منها يسمّي المعامل فيpath، وissueCountعدد المشكلات كلها.
{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid input", "issues": [ { "code": "too_big", "maximum": 100, "type": "number", "inclusive": true, "exact": false, "message": "Number must be less than or equal to 100", "path": ["limit"] } ], "issueCount": 1 }}ما رموز الأخطاء وما معنى كل منها؟
رابط القسم «ما رموز الأخطاء وما معنى كل منها؟»هذه كل الرموز التي تعيدها الواجهة:
| HTTP | code | متى يظهر | ما تفعله |
|---|---|---|---|
| 400 | VALIDATION_ERROR | معامل غير معروف، أو limit خارج المسموح، أو تاريخ غير صحيح، أو from بعد to، أو status غير معروف، أو مؤشر صفحة لا يُقرأ | أصلح الطلب ولا تعِده كما هو |
| 401 | UNAUTHORIZED | لا مفتاح، أو مفتاح غير صالح أو ملغى أو منتهٍ، أو حساب نشاط غير فعّال | راجع مفتاح API |
| 403 | FORBIDDEN | المفتاح صالح لكن ينقصه contacts.read أو bookings.read | أنشئ مفتاحًا بالصلاحية المطلوبة |
| 404 | NOT_FOUND | معرّف غير موجود في نشاطك، أو معرّف بصيغة غير صحيحة، أو مسار غير موجود | تحقق من المعرّف والمسار |
| 429 | RATE_LIMITED | تجاوزت حدود الطلبات | انتظر ثم أعد المحاولة |
| 500 | INTERNAL | خطأ غير متوقع في الخادم | أعد المحاولة بعد قليل |
المعرّف الذي ينتمي إلى نشاط آخر يعود بالخطأ 404 نفسه الذي يعود به المعرّف غير الموجود، فلا يكشف الرد أي شيء عن بيانات غيرك.
ما حدود الطلبات في واجهة مُجيب البرمجية؟
رابط القسم «ما حدود الطلبات في واجهة مُجيب البرمجية؟»لكل مفتاح 60 طلبًا في كل دقيقة، ويبدأ العدّ من جديد مع بداية الدقيقة التالية. كل طلب بمفتاح صالح يُحسب، حتى الذي يعود بالخطأ 400 أو 403 أو 404.
يحمل كل رد بمفتاح صالح ثلاث ترويسات تصف حد مفتاحك:
| الترويسة | معناها |
|---|---|
X-RateLimit-Limit | عدد الطلبات المسموح بها للمفتاح في الدقيقة |
X-RateLimit-Remaining | ما بقي للمفتاح في الدقيقة الحالية |
X-RateLimit-Reset | عدد الثواني حتى تبدأ دقيقة المفتاح من جديد |
وفوق حد المفتاح يوجد حد أوسع لكل عنوان شبكة، تشترك فيه كل الطلبات القادمة من العنوان نفسه، بأي مفتاح كانت. إذا وصلت إليه فإن ترويسات رد الخطأ 429 تصف ذلك الحد لا حد مفتاحك. أما رد الخطأ 401 فلا تعتمد على ترويساته في حساب حد مفتاحك.
ماذا أفعل عند الخطأ 429؟
رابط القسم «ماذا أفعل عند الخطأ 429؟»انتظر عدد الثواني المذكور في الترويسة Retry-After، ثم أعد الطلب نفسه. هكذا يبدو الرد عندما يستنفد المفتاح دقيقته:
HTTP/1.1 429 Too Many RequestsRetry-After: 60X-RateLimit-Limit: 60X-RateLimit-Remaining: 0X-RateLimit-Reset: 17Content-Type: application/json; charset=utf-8
{"error":{"code":"RATE_LIMITED","message":"At most 60 requests a minute per key."}}القيمة في X-RateLimit-Reset تقول متى تبدأ الدقيقة الجديدة فعلًا، وهي غالبًا أقل من Retry-After. انتظار أي منهما كافٍ. هذه دالة تنتظر وتعيد المحاولة:
async function getWithRetry(url, tries = 3) { for (let i = 0; ; i++) { const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.MUJIB_API_KEY}` } }); if (res.status !== 429 || i === tries - 1) return res; const wait = Number(res.headers.get('x-ratelimit-reset') ?? res.headers.get('retry-after') ?? '60'); await new Promise((r) => setTimeout(r, wait * 1000)); }}import osimport timeimport requests
def get_with_retry(url, params=None, tries=3): for i in range(tries): res = requests.get(url, params=params, timeout=30, headers={"Authorization": f"Bearer {os.environ['MUJIB_API_KEY']}"}) if res.status_code != 429 or i == tries - 1: return res wait = int(res.headers.get("X-RateLimit-Reset") or res.headers.get("Retry-After") or 60) time.sleep(wait)ما الأخطاء التي تستحق إعادة المحاولة؟
رابط القسم «ما الأخطاء التي تستحق إعادة المحاولة؟»أعد المحاولة عند 429 و500 فقط، وأصلح الطلب في كل حالة أخرى.
- 429: انتظر كما سبق، ثم أعد المحاولة.
- 500: أعد المحاولة بعد ثوانٍ، وضاعف الانتظار إذا تكرر الخطأ.
- 400 و401 و403 و404: إعادة الطلب نفسه تعيد الخطأ نفسه، وتستهلك من حدك. أصلح المعامل أو المفتاح أو المعرّف أولًا.
كيف أبقى داخل حدود الطلبات؟
رابط القسم «كيف أبقى داخل حدود الطلبات؟»اطلب صفحات أكبر، واطلب ما تغيّر فقط، ودع مُجيب يخبرك بالأحداث.
- اجعل
limitفي القوائم 100، فتقرأ أكبر عدد ممكن في كل طلب. انظر التقسيم إلى صفحات. - في العملاء استخدم
sinceلتطلب الجدد فقط، وفي الحجوزات استخدمfromوtoلتطلب الأيام التي تهمك. - إذا كنت تسأل الواجهة كل دقيقة لتعرف الجديد، فاستخدم Webhooks بدلًا من ذلك.
- اجعل لكل نظام مفتاحًا مستقلًا، فلكل مفتاح حده. وتذكّر أن الطلبات من خادم واحد تشترك في حد العنوان.
الأسئلة الشائعة
هل تُحسب الطلبات التي ترجع بخطأ ضمن الحد؟
نعم. كل طلب بمفتاح صالح يُحسب، حتى لو عاد بالخطأ 400 أو 403 أو 404. أما الطلب الذي يُرفض مفتاحه بالخطأ 401 فلا يُحسب على المفتاح.
هل لكل مفتاح حدّه الخاص؟
نعم. لكل مفتاح 60 طلبًا في الدقيقة، ولا يؤثر مفتاح في حد مفتاح آخر. لكن كل الطلبات من عنوان الشبكة نفسه تخضع أيضًا لحد أوسع مشترك.
هل أبني برنامجي على نص message في الخطأ؟
لا. ابنِ على رمز code فهو ثابت. نص message شرح بالإنجليزية للمطوّر وقد يتغيّر.
متى يبدأ العدّ من جديد؟
مع بداية كل دقيقة. الترويسة X-RateLimit-Reset تقول كم ثانية بقيت حتى ذلك.
مُجيب منتج شركة المجيب الذكي لتكنولوجيا المعلومات (ذات مسؤولية محدودة)، عمّان، الأردن. رقم التسجيل82888.