شرح رموز حالة HTTP

رمز حالة HTTP هو الرقم المكوّن من ثلاث خانات الذي يرسله الخادم مع كل استجابة ليقول ما حدث للطلب. تعطي الخانة الأولى الفئة — نجاح، أو إعادة توجيه، أو خطأ من العميل، أو خطأ في الخادم — ويعطي الرمز الكامل السبب المحدد. وقراءتها بشكل صحيح أسرع طريقة لتشخيص مشكلة في API، واختيارها بشكل صحيح من أوضح علامات الواجهة المصمّمة جيداً.

يشرح هذا الدليل الفئات الخمس، والرموز التي تقابلها يومياً، والفرق بين الرموز المتشابهة (401 مقابل 403، و301 مقابل 302، و502 مقابل 504)، والرمز الذي ينبغي لواجهتك إعادته في كل حالة.

الفئات الخمس

  • 1xx معلوماتية — استُلم الطلب والمعالجة مستمرة (100 Continue و101 Switching Protocols). نادراً ما يراها كود التطبيق.
  • 2xx نجاح — فُهم الطلب وقُبل.
  • 3xx إعادة توجيه — يجب على العميل فعل شيء آخر، عادةً اتباع عنوان URL جديد.
  • 4xx خطأ من العميل — الطلب خاطئ: صياغة سيئة، أو مصادقة مفقودة، أو مورد غير موجود. إعادة إرساله دون تغيير تعطي غالباً الجواب نفسه، والاستثناءات يعلنها الرمز نفسه، مثل 429 (أعد المحاولة لاحقاً بعد المدة المذكورة في Retry-After إن أُرسلت) و408 (يجوز تكرار الطلب).
  • 5xx خطأ في الخادم — الطلب صالح لكن الخادم فشل. قد تفيد إعادة المحاولة مع تراجع تدريجي حين يكون الفشل مؤقتاً (502 و503 و504)، لكن لا تُكرِّر تلقائياً إلا الطلبات المتكافئة (idempotent) مثل GET وPUT وDELETE؛ أما 501 فلن يتغير بإعادة المحاولة.

جرّبها: مرجع رموز حالة HTTP

2xx: رموز النجاح

  • 200 OK — النجاح القياسي؛ يحتوي الجسم على النتيجة.
  • 201 Created — أُنشئ مورد (بعد POST أو PUT)؛ تشير ترويسة Location إليه.
  • 202 Accepted — وُضع الطلب في قائمة الانتظار لمعالجة غير متزامنة؛ لم ينتهِ بعد.
  • 204 No Content — نجاح بلا جسم (نموذجي لـ DELETE وبعض PUT/PATCH).
  • 206 Partial Content — أُعيد نطاق من البايتات، ويُستخدم للتنزيلات القابلة للاستئناف والفيديو.

3xx: إعادة التوجيه

  • 301 Moved Permanently — تغيّر العنوان نهائياً؛ تحدّث المتصفحات ومحركات البحث سجلاتها. يُستخدم لتغييرات العنوان القياسي.
  • 302 Found — إعادة توجيه مؤقتة؛ يبقى العنوان الأصلي هو القياسي. قد تتغير الطريقة إلى GET.
  • 303 See Other — بعد POST، اذهب ونفّذ GET على هذا العنوان الآخر (نمط post/redirect/get).
  • 304 Not Modified — النسخة المخزّنة مؤقتاً ما زالت صالحة؛ لا يُرسل جسم. علامة على أن التخزين المؤقت يعمل.
  • 307 / 308 — إعادة توجيه مؤقتة ودائمة تضمن الحفاظ على الطريقة والجسم. فضّل 308 على 301 في واجهات API.

جرّبها: فاحص إعادة التوجيه

4xx: أخطاء العميل

  • 400 Bad Request — صياغة مشوّهة أو معاملات غير صالحة؛ خطأ التحقق العام.
  • 401 Unauthorized — لا بيانات اعتماد صالحة. رغم الاسم فهو يعني «غير مصادَق». أرسل ترويسة WWW-Authenticate.
  • 403 Forbidden — مصادَق لكنه غير مسموح له بهذا. إعادة المحاولة ببيانات الاعتماد نفسها لن تفيد.
  • 404 Not Found — لا مورد في هذا العنوان (أو يفضّل الخادم عدم الإفصاح عن وجوده).
  • 405 Method Not Allowed — العنوان موجود لكن ليس لهذه الطريقة (مثل DELETE على مورد للقراءة فقط). ضمّن ترويسة Allow.
  • 409 Conflict — يتعارض الطلب مع الحالة الراهنة: مفتاح فريد مكرر، أو إصدار قديم، أو عملية سبق تنفيذها.
  • 410 Gone — كان موجوداً وأُزيل عمداً ولن يعود.
  • 415 Unsupported Media Type — ترويسة Content-Type خاطئة في جسم الطلب.
  • 422 Unprocessable Content (سابقاً Unprocessable Entity) — الصياغة سليمة لكن القيم تفشل في التحقق. شائع الاستخدام لأخطاء الحقول.
  • 429 Too Many Requests — تجاوز حد المعدل؛ تخبرك ترويسة Retry-After بموعد المحاولة التالية.

جرّبها: محاكي رموز حالة API جرّبها: محلّل رموز حالة HTTP

5xx: أخطاء الخادم

  • 500 Internal Server Error — استثناء غير معالَج. ليس أبداً الجواب الصحيح للمدخلات السيئة؛ فهو يعني أن التحقق مفقود.
  • 501 Not Implemented — لا يدعم الخادم الطريقة إطلاقاً.
  • 502 Bad Gateway — تلقّى الوكيل أو موزّع الحمل استجابة غير صالحة من الخادم الخلفي (انهار أو أرسل بيانات تالفة).
  • 503 Service Unavailable — الخادم محمّل فوق طاقته أو في صيانة؛ مؤقت. أرسل Retry-After.
  • 504 Gateway Timeout — انتظر الوكيل الخادم الخلفي ولم يجب في الوقت المحدد.
502 و504 يرسلهما الوكيل أو موزّع الحمل، ليبلّغ أن الخادم الخلفي أعاد استجابة غير صالحة أو لم يجب في الوقت المحدد؛ أما 500 و503 فيصفان الخادم نفسه.
  • 500 Internal Server Error

    • العميل
    • الخادم
    1. 1 من العميل إلى الخادم: الطلب
    2. 2 الخادم داخليًا: استثناء غير معالَج
    3. 3 من الخادم إلى العميل: 500 ردّ
  • 502 Bad Gateway

    • العميل
    • الوكيل أو موزّع الحمل
    • الخادم الخلفي
    1. 1 من العميل إلى الوكيل أو موزّع الحمل: الطلب
    2. 2 من الوكيل أو موزّع الحمل إلى الخادم الخلفي: يمرّر الطلب
    3. 3 من الخادم الخلفي إلى الوكيل أو موزّع الحمل: استجابة غير صالحة ردّ انهار أو أرسل بيانات تالفة
    4. 4 من الوكيل أو موزّع الحمل إلى العميل: 502 ردّ

    النتيجة: يجيب الوكيل: الخادم الخلفي أعاد بيانات تالفة.

  • 503 Service Unavailable

    • العميل
    • الخادم
    1. 1 من العميل إلى الخادم: الطلب
    2. 2 الخادم داخليًا: محمّل فوق طاقته أو في صيانة
    3. 3 من الخادم إلى العميل: 503 ردّ

    النتيجة: مؤقت: ينبغي أن يرسل الخادم ترويسة Retry-After مع الرد.

  • 504 Gateway Timeout

    • العميل
    • الوكيل أو موزّع الحمل
    • الخادم الخلفي
    1. 1 من العميل إلى الوكيل أو موزّع الحمل: الطلب
    2. 2 من الوكيل أو موزّع الحمل إلى الخادم الخلفي: يمرّر الطلب
    3. 3 الوكيل أو موزّع الحمل داخليًا: ينتظر: لا رد في الوقت المحدد
    4. 4 من الوكيل أو موزّع الحمل إلى العميل: 504 ردّ

    النتيجة: يجيب الوكيل: الخادم الخلفي بطيء جداً.

حين يكون الفشل مؤقتاً (502 و503 و504) قد تفيد إعادة المحاولة مع تراجع تدريجي، لكن لا تُكرِّر تلقائياً إلا الطلبات المتكافئة (idempotent) مثل GET وPUT وDELETE.

جرّبها: مولّد استجابات حالة HTTP وهمية

رموز يخلط الناس بينها

  • 401 مقابل 403 — 401: من أنت؟ (سجّل الدخول). 403: أعرف من أنت، والجواب لا.
  • 301 مقابل 302 مقابل 308 — دائم مقابل مؤقت؛ ويحافظ 308 أيضاً على POST كما هو.
  • 400 مقابل 422 — 400 للطلبات غير القابلة للتحليل أو الخاطئة بنيوياً، و422 للطلبات سليمة البنية ذات القيم غير الصالحة. اختر اصطلاحاً واحداً والتزم به.
  • 502 مقابل 503 مقابل 504 — الخادم الخلفي أعاد بيانات تالفة، مقابل الخادم غير متاح، مقابل الخادم الخلفي بطيء جداً.
  • 404 مقابل 410 — غير معروف مقابل مُزال عمداً.

أي رمز يجب أن تعيده واجهتك؟

أعد الرمز الأكثر تحديداً الذي يصدق على الحالة، واستخدمه باتساق، وأرسل دائماً جسم خطأ بصيغة JSON برمز آلي ثابت ورسالة مفهومة. لا تغلّف الفشل أبداً في 200 — فالعملاء والمراقبة كلاهما يعتمد على سطر الحالة. حدّد المعدل بـ 429 وRetry-After، وتحقق بـ 400/422، وصادِق بـ 401، وفوّض بـ 403، واحتفظ بـ 500 للأخطاء البرمجية التي تنوي إصلاحها.

جرّبها: منشئ طلبات API جرّبها: محاكي رموز حالة API

الأسئلة الشائعة

ماذا يعني رمز الحالة 200؟

OK — نجح الطلب ويحمل جسم الاستجابة النتيجة. وهو رمز النجاح الافتراضي لـ GET.

ما الفرق بين 401 و403؟

401 يعني أن الطلب بلا مصادقة صالحة (سجّل الدخول أو أرسل رمزاً). و403 يعني أن الهوية معروفة لكن هذا الإجراء غير مسموح.

ماذا يعني خطأ 502 Bad Gateway؟

تلقّى وكيل أو موزّع حمل أمام التطبيق استجابة غير صالحة منه، أو لم يحصل على استجابة أصلاً — عادةً لأن خادم التطبيق انهار أو أُعيد تشغيله أو قطع الاتصال. أما إذا كان الخادم الخلفي بطيئاً في الرد فحسب، فيعيد الوكيل 504 بدلاً من ذلك.

ماذا يعني 429 Too Many Requests؟

تجاوز العميل حد المعدل. انتظر المدة المذكورة في ترويسة Retry-After قبل إرسال مزيد من الطلبات.

هل تعيد أخطاء التحقق 400 أم 422؟

كلاهما مقبول؛ 400 هو الخيار الكلاسيكي، و422 شائع في الواجهات الحديثة للتحقق على مستوى الحقول. الاتساق عبر الواجهة أهم من الاختيار.

هل 304 Not Modified خطأ؟

لا. يعني أن النسخة المخزّنة لدى العميل ما زالت حديثة، فلم يرسل الخادم جسماً. يوفّر عرض النطاق وهو علامة على أن ترويسات التخزين المؤقت تعمل.

المراجع

  • RFC 9110: HTTP SemanticsIETF · 2022معاني أساليب HTTP وحقول الترويسات ورموز الحالة والتفاوض على المحتوى، بغضّ النظر عن إصدار البروتوكول.
  • RFC 9457: Problem Details for HTTP APIsIETF · 2023صيغة الخطأ application/problem+json (type وtitle وstatus وdetail وinstance) لأخطاء API القابلة للقراءة آلياً.
  • HTTP response status codes — MDNMDN Web Docs (Mozilla)كل رمز حالة مع معناه واستخدامه المعتاد، من 100 إلى 511.

تمرين عملي

راجع رموز الحالة في واجهة الطلبيات لمتجر إلكتروني

المطلوب

أنت تختبر واجهة الطلبيات (Orders API) لمتجر بقالة إلكتروني (مثال خيالي)، والبناء ⁦2.6.0⁩ منشور على بيئة Staging. تحتوي المادة أدناه على اصطلاحات الفريق لواجهة API، وهي أساس الاختبار (Test basis) لرموز الحالة، وعلى أحد عشر طلباً من سجل الاختبار لديك مع الاستجابات التي تلقيتها. وقد أرسل إليك مطوّر تطبيق الجوال سؤالاً أيضاً.

قرّر لكل استجابة هل رمز الحالة والترويسات صحيحة، واكتب النتيجة المتوقعة حين لا تكون كذلك. ثم أجب المطوّر واختر الملاحظة التي ستبلغ عنها أولاً. تكفي الورقة والقلم، وخصّص نحو ⁦30⁩ دقيقة. تعطيك أداة «مرجع رموز حالة HTTP» معنى أي رمز. وإن أردت أن تحوّل نتائجك المتوقعة إلى فحص قابل للتكرار، فاكتب إحدى استجابات السجل بصيغتها الخام والصقها في أداة «مدقّق استجابات API»: فهي تفحص الاستجابة مقابل الحالة التي تتوقعها والترويسات التي يجب أن تكون موجودة، مثل Location أو WWW-Authenticate أو Retry-After.

المادة
متجر بقالة إلكتروني (مثال خيالي) - واجهة الطلبيات Orders API
البناء 2.6.0 على بيئة Staging
العنوان الأساسي: https://staging.grocery.example/api

اصطلاحات الفريق لواجهة API (أساس الاختبار لرموز الحالة)
  C1  الإنشاء: 201 Created مع ترويسة Location تحمل عنوان الطلبية الجديدة.
  C2  التحقق من المدخلات: 400 إذا تعذّر تحليل الجسم،
      و422 إذا حُلّل لكن إحدى القيم غير صالحة.
      لكل خطأ جسم JSON بالشكل {"error":{"code":"...","message":"..."}}.
  C3  المصادقة: 401 مع "WWW-Authenticate: Bearer" إذا غاب رمز الوصول أو انتهت صلاحيته،
      و403 إذا كان رمز الوصول صالحاً لكن الإجراء غير مسموح.
  C4  الخصوصية: يُجاب عن طلبية عميل آخر تماماً كما يُجاب عن طلبية غير موجودة (404).
  C5  الحالة: الإجراء الذي لا تسمح به حالة الطلبية الحالية يُجاب بـ 409.
  C6  حد المعدل: 60 طلباً في الدقيقة لكل رمز وصول، ثم 429 مع Retry-After.
  C7  الإصدارات: مسارات /v1 يُعاد توجيهها نهائياً إلى /v2 مع الحفاظ على الطريقة والجسم.
  C8  لا يُعاد الفشل أبداً مع الرمز 200.

سجل الاختبار - برمز وصول العميل A ما لم يُذكر غير ذلك، والأجسام مختصرة
  R1   POST /v2/orders   سلة صالحة من 3 أصناف
       -> 200 OK   {"id":58213,"status":"PLACED",...}   دون ترويسة Location
  R2   POST /v2/orders   "quantity": 0 في أحد الأصناف (تشترط مواصفة API قيمة 1 أو أكثر)
       -> 500 Internal Server Error   {"error":{"code":"INTERNAL",...}}
  R3   POST /v2/orders   جسم مقطوع بعد 40 بايتاً (JSON غير صالح)
       -> 400 Bad Request   {"error":{"code":"MALFORMED_JSON",...}}
  R4   GET /v2/orders/58213   دون ترويسة Authorization
       -> 403 Forbidden   دون ترويسة WWW-Authenticate
  R5   GET /v2/orders/58101   طلبية تخص العميل B
       -> 404 Not Found   الترويسات والجسم مطابقة لما يُعاد للطلبية غير الموجودة 99999999
  R6   POST /v2/orders/58090/cancel   الطلبية شُحنت بالفعل
       -> 200 OK   {"status":"error","message":"Order already shipped"}
  R7   GET /v2/orders?page=2   الطلب الحادي والستون خلال دقيقة واحدة
       -> 429 Too Many Requests   دون ترويسة Retry-After
  R8   POST /v1/orders   سلة صالحة (المسار الذي تستخدمه إصدارات التطبيق القديمة)
       -> 301 Moved Permanently   Location: /api/v2/orders
       يتبعها عميل HTTP بطلب GET /v2/orders -> 200 OK (قائمة الطلبيات)؛ لم تُنشأ أي طلبية
  R9   GET /v2/orders/58213   If-None-Match: "a7f3" (وسم ETag للنسخة المخزّنة في التطبيق)
       -> 304 Not Modified   دون جسم؛ لم تتغير الطلبية منذ تخزينها
  R10  GET /v2/orders/58213   الساعة 14:02 أثناء نشر على بيئة Staging
       -> 502 Bad Gateway   صفحة خطأ HTML من موزّع الحمل
  R11  GET /v2/orders?from=2019-01-01&to=2026-09-30   السجل الكامل للعميل A
       -> 504 Gateway Timeout بعد 30 ثانية   صفحة خطأ HTML من موزّع الحمل

سؤال من مطوّر تطبيق الجوال
  «عميل HTTP لدينا يعيد تلقائياً إرسال أي طلب تأتي استجابته 5xx، حتى 3 مرات.
   هل هذا آمن لهذه الطلبات؟»
الخطوات
  1. اكتب لكل صف رمز الحالة والترويسات التي تتوقعها الاصطلاحات قبل أن تنظر إلى الاستجابة الفعلية.
  2. قارن بالاستجابة الفعلية وصنّف الصف: صحيح، أو عيب، أو سؤال للفريق. واذكر للعيب الاصطلاح الذي يخالفه (⁦C1–C8⁩) أو قاعدة الدليل التي يكسرها.
  3. في R10 وR11، اذكر ما يخبرك به رمز البوابة عن موضع المشكلة، وما الذي ستسجله وتعيد اختباره.
  4. أجب عن سؤال المطوّر لكل طلب جاءت استجابته 5xx: هل يجوز للتطبيق أن يعيد إرساله تلقائياً، ولماذا؟ ثم اذكر هل في السجل استجابة أخرى تسمح بإعادة المحاولة، ومتى.
  5. اختر الملاحظة التي ستبلغ عنها أولاً، واكتب عنوان تقرير العيب الخاص بها، واذكر سبب أولويتها.
إظهار الإجابة النموذجية
الإجابة النموذجية

الخلاصة: ستة عيوب في رموز الحالة أو الترويسات (R1 وR2 وR4 وR6 وR7 وR8)، وثلاث استجابات صحيحة (R3 وR5 وR9)، ورمزان من البوابة صحيحان لكنهما يشيران إلى مشكلة خلفها (R10 للتحقيق، وR11 عيب). وفيما يلي التفاصيل صفاً صفاً، والنتيجة المتوقعة في كل منها مأخوذة من الاصطلاحات.

R1 — عيب (C1). النتيجة المتوقعة: 201 Created مع Location: /api/v2/orders/58213. فالرمز 200 يقول «نجح الأمر» فقط، ولا يقول إن مورداً جديداً قد أُنشئ، والتطبيق الذي يتحقق من 201، أو يقرأ ترويسة Location ليفتح الطلبية الجديدة، لا يستطيع الاعتماد على هذه الاستجابة.

R2 — عيب (C2). الجسم قابل للتحليل، والقيمة 0 تخالف قاعدة «1 أو أكثر»، لذا فالنتيجة المتوقعة 422 مع خطأ JSON يسمّي الحقل quantity. والرمز 500 هو الإخفاق (Failure)، والعيب الذي خلفه غياب التحقق من المدخلات: فقد وصلت القيمة إلى شيفرة لم تستطع التعامل معها، و500 ليس أبداً الجواب الصحيح للمدخلات السيئة. ولأن 0 و1 هما القيمتان الحدّيتان لهذه القاعدة، تأكد أن القيمة 1 مقبولة، وجرّب أيضاً -1 و1.5 و"two" وغياب الكمية، لتعرف إلى أي مدى يمتد غياب التحقق.

R3 — صحيح (C2). الجسم الذي يتعذّر تحليله يحصل على 400 مع جسم خطأ JSON. أما 422 فخطأ هنا، لأنه لم يُقرأ شيء يمكن التحقق من قيمه.

R4 — عيب (C3). غياب رمز الوصول يعني «غير مصادَق»، فالنتيجة المتوقعة 401 Unauthorized مع WWW-Authenticate: Bearer، ويوجب RFC 9110 هذه الترويسة في كل استجابة 401. أما 403 فيقول للتطبيق «أنت مسجّل الدخول، لكن هذا غير مسموح لك»، فيعرض خطأ صلاحيات بدلاً من أن يرسل العميل إلى شاشة تسجيل الدخول. أعد الاختبار برمز وصول منتهي الصلاحية أيضاً لأن C3 تشمل الحالتين، واحتفظ بفحص يؤكد أن 403 ما زال يظهر في موضعه: رمز وصول صالح يُستخدم لإجراء غير مسموح له.

R5 — صحيح (C4). الطلبية موجودة لكنها تخص العميل B. وقد اختار الفريق 404 كي لا تكشف الواجهة أرقام الطلبيات الموجودة، وهو استخدام لـ 404 يذكره الدليل (حين يفضّل الخادم عدم الإفصاح عن وجود المورد). ولو أعادت الواجهة 403 هنا لكان ذلك عيباً مخالفاً لـ C4، لأنه يؤكد أن الطلبية 58101 موجودة. والفحص المهم هو المقارنة: يجب أن تتطابق الحالة والترويسات والجسم مع ما يُعاد للطلبية غير الموجودة 99999999، وهي متطابقة.

R6 — عيب (C5 وC8). النتيجة المتوقعة: 409 Conflict مع جسم خطأ JSON، لأن الإلغاء يتعارض مع حالة الطلبية الراهنة (شُحنت بالفعل). والرمز 200 مع "status":"error" يخفي الفشل: فقد يخبر التطبيقُ العميلَ أن طلبيته أُلغيت، وتحسب المراقبة الاستدعاء نجاحاً. وتحقّق كذلك من الآثار الجانبية: يجب أن تبقى حالة الطلبية «شُحنت»، وألا يكون قد بدأ أي استرداد للمبلغ.

R7 — عيب (C6). الرمز 429 صحيح عند الطلب الحادي والستين، لكن ترويسة Retry-After التي تشترطها C6 مفقودة، فلا يعرف التطبيق متى يعيد المحاولة: إما أن يرسل مزيداً من الطلبات فتُرفض بـ 429، وإما أن ينتظر أكثر من اللازم. وافحص الحدّ أيضاً: يجب أن ينجح الطلب الستون في الدقيقة نفسها.

R8 — عيب (C7). النتيجة المتوقعة: 308 Permanent Redirect مع Location: /api/v2/orders. فمع 301 يجوز لعميل HTTP أن يغيّر POST إلى GET (يسمح RFC 9110 بذلك لأسباب تاريخية)، وهذا ما حدث بالضبط: لم تصل السلة إلى /v2، ولم تُنشأ أي طلبية، وآخر استجابة في السلسلة 200، فقد يعرض التطبيق نجاحاً. ونصيحة الدليل أن تفضّل 308 على 301 في واجهات API. واسأل أي إصدارات التطبيق ما زالت تستدعي /v1، فالجواب يحدد مدى الاستعجال.

R9 — صحيح. الرمز 304 ليس خطأ: لم تتغير الطلبية منذ خزّنها التطبيق مع وسم ETag "a7f3"، فلم يرسل الخادم جسماً، ويعرض التطبيق نسخته المخزّنة. واختبر الحالة المعاكسة أيضاً: بعد أن تتغير الطلبية (بعد إلغائها مثلاً) يجب أن يعيد الطلب نفسه 200 مع الجسم الجديد ووسم ETag جديد، وإلا رأى العملاء حالة قديمة.

R10 — ليس عيباً في رمز الحالة، بل سؤال للتحقيق. يعني 502 أن موزّع الحمل تلقّى من التطبيق استجابة غير صالحة أو لم يتلقَّ استجابة أصلاً، وهذا يتفق مع إعادة تشغيل خادم التطبيق أثناء النشر في الساعة ⁦14:02⁩. سجّل الوقت والبناء والطلب، وأعد الاختبار بعد انتهاء النشر. فإن ظهر 502 خارج أوقات النشر فهو يدل على انهيار التطبيق أو قطعه الاتصالات، فأبلغ عنه مع سجلات التطبيق. وسؤالان للفريق: هل ينبغي أن يتوقف موزّع الحمل عن إرسال الطلبات إلى الخادم قبل إعادة تشغيله أثناء النشر، حتى لا يرى أي عميل HTTP الرمز 502؟ وهل يتعامل التطبيق مع صفحة خطأ HTML حيث تعد C2 بجسم JSON؟

R11 — الرمز 504 نفسه صحيح: انتظر موزّع الحمل 30 ثانية ولم يُجب التطبيق في الوقت المحدد. أما العيب فخلفه: البحث في سجل طويل (من 2019 إلى 2026) لا ينتهي خلال الثلاثين ثانية التي تسمح بها البوابة. ضيّق النطاق الزمني لتعرف تقريباً من أين يبدأ الإخفاق، وسجّل أزمنة الاستجابة، وأبلغ عنه عيباً في الأداء. واسأل مالك المنتج هل يوجد حد أقصى للنطاق الزمني: فإن وُجد، فالنطاق الذي لن تخدمه الواجهة ينبغي أن يُرفض بـ 422 (C2) بدلاً من أن تنتهي مهلته. ولن تفيد إعادة الطلب نفسه.

سؤال المطوّر: ليس آمناً بصيغته الحالية. لا تُعَد المحاولة تلقائياً إلا إذا اجتمع شرطان: أن يكون الرمز مؤقتاً (502 أو 503 أو 504)، وأن تكون الطريقة متكافئة (idempotent) مثل GET وPUT وDELETE. ولا يجوز إعادة R2 لسببين: الرمز 500 فيه ناتج عن الطلب نفسه، فيعود كما هو في كل مرة؛ وPOST ليست متكافئة، وهذا هو الخطر الأكبر: فإذا حصل POST /v2/orders على 502 أو 504 فربما أنشأ الخادم الطلبية قبل أن تضيع الاستجابة، وقد تُنشئ إعادة المحاولة التلقائية طلبية ثانية. لذلك ينبغي أن يتحقق التطبيق بعد POST فاشل من قائمة الطلبيات بطلب GET قبل أن يعرض إعادة الإرسال، وأن يوضح المطوّرون كيف تمنع الواجهة الطلبيات المكررة. أما R10 فإعادته آمنة (GET، ورمز مؤقت، مع تراجع تدريجي). وR11 طلب GET أيضاً، لكن تكرار طلب أثقل من اللازم لا يضيف إلا حملاً ثم تنتهي مهلته مجدداً، فاجعل عدد المحاولات صغيراً واستخدم التراجع التدريجي. وأخيراً، 429 من فئة 4xx ويجوز إعادة إرساله، لكن بعد مدة Retry-After فقط، وهذا سبب آخر لأهمية R7.

أبلغ عن R8 أولاً. مثال للعنوان: «POST /v1/orders يعيد 301 بدلاً من 308، فيعيد عميل HTTP إرساله بطريقة GET ولا تُنشأ أي طلبية». وهو الأول لأن العملاء على أي تطبيق ما زال يستدعي /v1 يخسرون طلبياتهم دون أي رسالة خطأ، وتنتهي السلسلة بـ 200. ثم R6 (إلغاء فاشل يُعرض نجاحاً) وR4 (غياب رمز الوصول يُعرض مشكلةَ صلاحيات، فلا يرسل التطبيق العميل إلى تسجيل الدخول). وإن قدّمت R6 لأنك تعرف أن كل التطبيقات انتقلت إلى /v2 فهذا سبب وجيه؛ المهم أن تأتي الأولوية من الأثر على العملاء. وبعد الإصلاحات، أعد تنفيذ الصفوف نفسها اختباراتِ تأكيد (Confirmation testing).

لتتحقق من عملك: يجب أن يكون لكل صف الرمز المتوقع، ومعه الترويسة حين تشترطها الاصطلاحات (Location وWWW-Authenticate وRetry-After). وإن صنّفت R3 أو R5 أو R9 عيباً، فأعد قراءة ما يقوله الدليل عن 400 مقابل 422، وعن 404 (قد يفضّل الخادم عدم الإفصاح عن وجود المورد)، وعن 304 (ليس خطأ).

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة

الأدوات المذكورة في هذا الدليل

ابحث عن أي رمز حالة HTTP لمعرفة معناه ومرجعه في RFC ومتى يُستخدم.

الويب

تحليل رمز حالة HTTP وترويسات الاستجابة، مع شرح يبيّن ما إذا كان الرمز صحيحاً في هذا الموقف.

التحقق

احصل على نقطة نهاية عامة تعيد أي رمز حالة HTTP، مع تأخير اختياري وجسم JSON مخصّص، لاختبار معالجة الأخطاء في العميل.

اختبار واجهات API

تتبّع سلاسل إعادة التوجيه (301/302/307/308) وعرض كل قفزة وحالتها وعنوان URL النهائي.

الويب

أنشئ طلبات HTTP وأرسلها (الطريقة وعنوان URL والترويسات والمصادقة والجسم) وافحص الاستجابة — بديل خفيف لـ Postman داخل متصفحك.

اختبار واجهات API

اختبار إعدادات CORS: إرسال طلبات تمهيدية (preflight) وطلبات بسيطة من أصل محدّد وفحص ترويسات Access-Control-*.

الويب

كيف تساعدك متقن سوفت

أدلة أخرى

أدلة أخرى
اختبار واجهات API

ما هو اختبار API؟ وكيف تختبر REST API

شرح اختبار API: ما هو، وما الذي تفحصه في كل طلب واستجابة، وطريقة خطوة بخطوة لاختبار REST API، والأخطاء الشائعة، وأدوات مجانية من متصفحك.

وقت القراءة 6 دقائق
الأداء

اختبار مرونة الأداء والأمان

كيف تختبر المنتج أمام الحمل والاعتماديات الفاشلة والهجمات: اختبارات الحمل والإجهاد والتحمّل بأهداف حقيقية، وحقن الأعطال، وخط أساس OWASP، والأرقام التي تُسجَّل.

وقت القراءة 8 دقائق
اختبار واجهات API

مقارنة أساليب اختبار الواجهات البرمجية

خمس طرق لاختبار واجهة برمجية — الاستكشافية والمكتوبة والعقد والمحاكاة والحمل — مقارنة فيما يلتقطه كل منها، وكيف تختلف REST وGraphQL وSOAP وWebhooks.

وقت القراءة 6 دقائق
الأداء

اختبار المرونة

ما اختبار المرونة وكيف يختلف عن اختبار الأداء وكيف يُنفَّذ: المتطلبات، وتجارب حقن الأعطال، وأنماط الاستقرار، والأدوات، وخطة جاهزة ليوم تمرين.

وقت القراءة 22 دقائق
JSON والبيانات

ما هو JSON؟

شرح JSON بلغة مبسّطة: ما هو، وأنواع القيم الست، وقواعد الصياغة التي يخطئ فيها الكثيرون، وكيفية تنسيقه والتحقق منه، ومقارنته بـ XML وYAML.

وقت القراءة 4 دقائق
الأمان

ما هو JWT؟ شرح رموز JSON Web Token

شرح مبسّط لـ JWT: الأجزاء الثلاثة للرمز، والمطالبات مثل exp وsub، وكيفية فك ترميزه والتحقق منه، ولماذا فك الترميز ليس تحققاً، وقواعد الأمان.

وقت القراءة 4 دقائق