# تصميم واجهة مراسلة REST: الموارد والطرق ورموز الحالة

> تُنمذِج واجهة مراسلة REST كل عملية إرسال كمورد داخل مجموعة رسائل messages. يُرسِل العميل رسالة عبر POST، وبما أن التسليم غير متزامن، يعيد الخادم 202 Accepted مع معرّف رسالة وعنوان حالة، ثم يُبلّغ بالنتيجة النهائية عبر webhook. وتتبع طرق HTTP ورموز الحالة دلالات RFC 9110.

- الرابط الأساسي: https://www.broadnet.me/ar/reference/rest-messaging-api-design
- اللغة: ar
- آخر تحديث: 2026-07-19
- الناشر: BroadNet (https://www.broadnet.me)

كيف تُنمذَج واجهة مراسلة REST قائمة على المعايير: مجموعة رسائل messages، وطرق HTTP ودلالات رموز الحالة وفق RFC 9110، والإرسال المتزامن مقابل غير المتزامن (202 Accepted مع ردّ حالة)، والتفاوض على المحتوى والإصدار عبر عنوان URL أو الترويسة — مع جدول موازنة بين REST وSMPP.

## نموذج مورد الرسائل

تعامل واجهة مراسلة REST كل رسالة كمورد ضمن مجموعة — يُصطلح على أنها /messages — يُعنوَن بمعرّف يُسنِده الخادم. والفعل، لا حقلٌ في الحمولة، هو ما يُعبّر عن القصد: يُنشئ POST /messages رسالة صادرة جديدة ويضعها في الطابور؛ ويقرأ GET /messages/{id} حالتها الراهنة؛ ويسرد GET /messages المجموعة ويرشّحها. وهذه هي طبقة REST القائمة فوق وصلات المشغّلين ذاتها التي يبلغها SMPP على السلك، فالمورد الذي يُرسله العميل عبر POST يُطابَق، عند الطبقة الدنيا، بأمر submit_sm على جلسة SMPP مربوطة. ولأن المعرّف يُسكّه الخادم ويُعيده في الاستجابة (وعادةً ما يُردَّد في ترويسة Location)، يحصل العميل على مقبض ثابت للاستقصاء أو للمطابقة لاحقًا مع ردود الحالة.

*إنشاء رسالة داخل المجموعة (نمط REST العام)*

```http
POST /v1/messages HTTP/1.1
Host: api.example
Content-Type: application/json
Authorization: Bearer <token>
Idempotency-Key: 8f14e45f-ea7b-4c0f-9b2a-1d2c3e4f5a6b

{
  "to": "+15551234567",
  "from": "BRANDNAME",
  "text": "Your one-time code is 401 928",
  "callback_url": "https://app.example/webhooks/dlr"
}
```

## طرق HTTP وضماناتها

يُعرّف RFC 9110 خاصّيتين تحكمان كيفية معاملة عميل المراسلة وأي وسيط للطلب. فالطرق الآمنة (GET وHEAD) لا آثار جانبية لها وقابلة للتخزين المؤقت وإعادة الإرسال بحرّية. والطرق المتكافئة (GET وHEAD وPUT وDELETE) يمكن تكرارها بالأثر الصافي نفسه. أما POST فليست آمنة ولا متكافئة، وهذا بالضبط هو الإشكال في تقديم الرسائل: قد يؤدي POST مُعاد إلى إرسال مزدوج. والعلاج القياسي ليس إساءة استعمال PUT، بل الإبقاء على POST وجعلها متكافئة عبر ترويسة الطلب Idempotency-Key، بحيث يعيد التقديمُ المُعاد النتيجةَ الأصلية بدل إنشاء رسالة ثانية.

*طرق HTTP على مورد الرسائل (RFC 9110)*

| الطريقة | على /messages | آمن | Idempotent |
|---|---|---|---|
| POST | إنشاء رسالة جديدة وإضافتها إلى قائمة الانتظار | No | لا (اجعلها idempotent عبر Idempotency-Key) |
| GET | اقرأ رسالة أو اعرض المجموعة | نعم | نعم |
| HEAD | البيانات الوصفية / التحقق من الوجود | نعم | نعم |
| PUT | استبدال مورد قابل للتغيير (مثل إعدادات webhook) | No | نعم |
| PATCH | تحديث جزئي لمورد قابل للتغيير | No | No |
| DELETE | إلغاء رسالة لا تزال في قائمة الانتظار | No | نعم |

## دلالات رمز الحالة للإرسال

يُرمِّز رمز الحالة الذي يعيده الخادم ما إذا كانت الرسالة قد قُبِلت أو أُنجزت أو رُفِضت — وإرسال الرسائل يكون في الغالب الأعمّ غير متزامن. ويُعرّف RFC 9110 رمز 202 Accepted لهذه الحالة تحديدًا: قُبِل الطلب للمعالجة لكن المعالجة لم تكتمل، وينبغي أن تصف الاستجابةُ مكان متابعتها. لذا تعيد واجهة المراسلة 202 لإرسالٍ في الطابور، محتفظةً بـ 201 Created لموردٍ تمثّل بالكامل، و200 OK لعملية متزامنة فعلًا. أما أخطاء العميل (حمولة مشوّهة أو وجهة غير صالحة أو مرسِل مجهول) فهي 4xx ويجب ألّا يُعاد إرسالها دون تغيير؛ وإخفاقات الخادم والطبقة العليا هي 5xx وآمن إعادة إرسالها بتباطؤ تدريجي تحت الـ Idempotency-Key نفسه.

*دلالات رمز الحالة لتقديم الرسائل (RFC 9110)*

| الرمز | المعنى | متى تستخدمه واجهة API للمراسلة |
|---|---|---|
| 202 Accepted | مقبول، لكن المعالجة غير مكتملة | إرسال غير متزامن إلى قائمة الانتظار؛ الحالة النهائية تصل عبر callback |
| 201 Created | تم إنشاء المورد | إنشاء متزامن عندما يكون المورد مكتملًا |
| 200 OK | تم إتمام الطلب | قراءة حالة متزامنة أو عملية فورية فعلًا |
| 400 / 422 | خطأ من جانب العميل / غير قابل للمعالجة | متن مشوّه أو حقل غير صالح — لا تُعِد المحاولة دون تغيير |
| 401 / 403 | غير موثق / ممنوع | بيانات اعتماد مفقودة أو غير كافية |
| 409 Conflict | تعارض الحالة | إعادة استخدام Idempotency-Key مع حمولة مختلفة |
| 429 Too Many Requests | تم تجاوز حد المعدل | قلّل المعدل؛ التزم بـ Retry-After وتراجع (backoff) |
| 5xx | فشل الخادم / الطرف السابق (upstream) | مؤقت — أعد المحاولة مع backoff بنفس المفتاح |

## التسليم المتزامن مقابل غير المتزامن

ثمة زمنا استجابة متمايزان في واجهة المراسلة، وخلطهما خطأ تصميمي. فزمن استجابة الواجهة هو المدة التي يستغرقها نداء HTTP لقبول الرسالة؛ وزمن استجابة التسليم هو المدة التي تستغرقها شبكة المشغّل لتسليم الرسالة إلى الهاتف وإعادة إيصال. ولأن الثاني غير محدود وخارج سيطرة المرسِل، فإن الواجهة المحكمة التصميم تُقرّ فورًا (202) بحالة قُبِلت أو في الطابور، ثم تُسلّم النتيجة النهائية بشكل غير متزامن — عبر ردّ حالة تسليم (نظير HTTP لإيصال تسليم SMPP). والعملاء الذين يحتاجون الحالة النهائية إمّا يشتركون في الردّ (دفع) أو يستقصون GET /messages/{id} (سحب)؛ ويُفضَّل الردّ لأنه يتجنّب حِمل الاستقصاء ويُبلّغ بتغيّرات الحالة خلال ثوانٍ.

*استجابة 202 Accepted مع مقبض حالة*

```http
HTTP/1.1 202 Accepted
Location: /v1/messages/01HZY8Q3M6
Content-Type: application/json

{
  "id": "01HZY8Q3M6",
  "status": "accepted",
  "created_at": "2026-07-19T09:15:22Z",
  "status_url": "/v1/messages/01HZY8Q3M6"
}
```

## التفاوض على المحتوى والإصدار

يتّفق العملاء والخوادم على التمثيل عبر ترويسات التفاوض على المحتوى في RFC 9110: يحمل الطلب Content-Type للجسم الذي يرسله وAccept لما يريده في المقابل، ويُردِّد الخادم نوع الوسائط المختار في Content-Type للاستجابة. وتوحّد معظم واجهات المراسلة على application/json وتستخدم application/problem+json للأخطاء. ولإصدار الواجهة نمطان رائجان. فإصدار عنوان URL (‏/v1/messages) صريح وودود للتخزين المؤقت وسهل التوجيه، على حساب ترقية خشنة للسطح كلّه. وإصدار الترويسة أو نوع الوسائط (‏Accept: application/vnd.example.v2+json) يُبقي العناوين ثابتة ويتيح للمورد التطوّر مستقلًّا، على حساب كونه غير مرئي في المتصفّح وأصعب اختبارًا يدويًا. وأيًّا كان المختار، يجب ألّا تستلزم التغييرات الإضافية (حقول اختيارية جديدة) ترقية إصدار؛ بل التغييرات الكاسرة وحدها.

*مقاربات إصدار الواجهة*

| النهج | مثال | المفاضلة |
|---|---|---|
| مسار URL | /v1/messages | صريح، قابل للتخزين المؤقت، سهل التوجيه؛ زيادات إصدار كبيرة وغير دقيقة |
| رأس مخصص | Api-Version: 2026-07-19 | URLs نظيفة، مثبتة بتاريخ؛ غير مرئية لذاكرة التخزين المؤقت والمتصفحات |
| قبول نوع الوسائط | Accept: application/vnd.example.v2+json | تطوّر لكل مورد؛ أصعب في الاختبار يدويًا |
| معلمات الاستعلام | /messages?version=2 | بسيط؛ يُربك التخزين المؤقت وهوية المورد |

## REST مقابل SMPP: اختيار وسيلة النقل

طبقة HTTP/REST وSMPP وسيلتا نقل إلى شبكة المراسلة نفسها، والمرسِلون الناضجون يستخدمون كلتيهما. فـ REST هو الخيار الصائب لتكامل التطبيقات: عديم الحالة، وودود لجدران الحماية عبر HTTPS الاعتيادي، وسهل التأمين برموز bearer، وبسيط للقياس. وSMPP هو الخيار الصائب للإنتاجية العالية المستدامة والحد الأدنى من الكلفة لكل رسالة، لأن الجلسة الثنائية طويلة الأمد تتجنّب كلفة الاتصال لكل رسالة وتمنح تحكّمًا دقيقًا في النافذة. ويقابل الجدولُ بين الاثنين ليطابق المُكامِلُ وسيلةَ النقل مع عبء العمل؛ ولوصلات REST الفعلية لدى BroadNet راجع مرجع واجهة المطوّرين، وللبروتوكول على السلك راجع نظرة عامة على SMPP.

*REST (‏HTTP) مقابل SMPP كوسيلة نقل للمراسلة*

| الخاصية | REST / HTTP | SMPP |
|---|---|---|
| النموذج | طلب/استجابة بدون حالة عبر HTTPS | جلسة ثنائية طويلة الأمد ذات حالة (bind) |
| التأطير | JSON عبر HTTP/1.1 أو HTTP/2 | قيم PDU الثنائية (submit_sm، deliver_sm) |
| إيصال التسليم | Webhook للحالة / استطلاع GET | إيصال deliver_sm في نفس الجلسة |
| معدل الإنتاجية | جيد؛ تكلفة إضافية لكل طلب | الأعلى على المدى المستمر؛ قائم على النافذة، حمل إضافي منخفض |
| المصادقة | رمز حامل / مفتاح API / OAuth 2.0 | system_id + كلمة المرور عند الربط |
| التحكم في التدفق | 429 + ترويسات Retry-After وRateLimit | حجم النافذة + تقييد enquire_link |
| الأفضل لـ | تكامل التطبيقات، وخطافات الويب، وحجم متوسط | تدفقات A2P ضخمة الحجم بمستوى المشغّلين |

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

### لماذا تعيد واجهة مراسلة REST رمز 202 بدل 200 أو 201؟

لأن تسليم الرسائل غير متزامن. يُعرّف RFC 9110 رمز 202 Accepted بأنه «قُبِل للمعالجة، والمعالجة لم تكتمل»، وهذا يصف بالضبط إرسالًا في الطابور. تُقرّ الواجهة فورًا بمعرّف رسالة ومقبض حالة، ثم تُبلّغ لاحقًا بنتيجة التسليم النهائية عبر ردّ. أما 201 و200 فيدلّان على أن العملية أُنجزت بالفعل.

### كيف ينبغي نمذجة مورد الرسائل؟

كمجموعة: يُنشئ POST /messages رسالة ويضعها في الطابور، ويقرأ GET /messages/{id} حالتها، ويسرد GET /messages المجموعة ويرشّحها. ويسكّ الخادمُ المعرّف ويعيده (غالبًا في ترويسة Location) ليحصل العميل على مقبض ثابت للاستقصاء أو للمطابقة مع ردود الحالة.

### طريقة POST ليست متكافئة — فكيف نتجنّب الإرسال المزدوج؟

تُبقي على POST (فهي تُعبّر بصواب عن «أنشئ رسالة جديدة») وتجعلها متكافئة بترويسة الطلب Idempotency-Key. فالتقديمُ المُعاد الحامل للمفتاح نفسه يعيد النتيجة الأصلية بدل إنشاء رسالة ثانية. أما إساءة استعمال PUT لفرض التكافؤ فتكسر نموذج مورد REST.

### ما الفرق بين زمن استجابة الواجهة وزمن استجابة التسليم؟

زمن استجابة الواجهة هو المدة التي يستغرقها نداء HTTP لقبول الرسالة؛ وزمن استجابة التسليم هو المدة التي تستغرقها شبكة المشغّل لبلوغ الهاتف وإعادة إيصال. والثاني غير محدود وخارج سيطرة المرسِل، ولهذا تُقرّ الواجهة بسرعة (202) وتُبلّغ بالتسليم النهائي بشكل غير متزامن.

### هل أُصدِر واجهة المراسلة في عنوان URL أم في ترويسة؟

إصدار عنوان URL (‏/v1/messages) صريح وودود للتخزين المؤقت وسهل التوجيه لكنه يرقّي السطح كلّه دفعة واحدة. وإصدار الترويسة أو نوع الوسائط يُبقي العناوين ثابتة ويتيح للموارد التطوّر مستقلّةً لكنه غير مرئي للتخزين المؤقت وأصعب اختبارًا يدويًا. وفي كلتا الحالتين، يجب ألّا تفرض التغييرات الإضافية ترقية إصدار.

### متى أستخدم REST مقابل SMPP؟

استخدم REST لتكامل التطبيقات: عديم الحالة، وودود لجدران الحماية عبر HTTPS، ومصادقة برموز bearer، وسهل القياس. واستخدم SMPP لأعلى إنتاجية مستدامة وأدنى كلفة لكل رسالة، حيث تُؤتي الجلسة الثنائية طويلة الأمد ذات النافذة ثمارها. وكلتاهما تبلغان شبكة المراسلة نفسها؛ وكثير من المرسِلين يُشغّلون REST لحركة التحكّم وSMPP لتدفّقات A2P عالية الحجم.

## المصادر

- [IETF RFC 9110 — HTTP Semantics](https://datatracker.ietf.org/doc/html/rfc9110)
- [IETF RFC 9111 — HTTP Caching](https://datatracker.ietf.org/doc/html/rfc9111)

## ذو صلة

- [نظرة عامة على بروتوكول SMPP](https://www.broadnet.me/ar/reference/smpp-protocol-overview)
- [تسليم webhook وموثوقيته](https://www.broadnet.me/ar/reference/webhook-delivery-and-reliability)
- [التكافؤ وتحديد المعدّل](https://www.broadnet.me/ar/reference/idempotency-and-rate-limiting)
- [أخطاء الواجهة وترقيم الصفحات](https://www.broadnet.me/ar/reference/api-errors-and-pagination)
- [مرجع واجهة BroadNet](https://www.broadnet.me/ar/developers/api-reference)
