قواعد تسمية REST API: دليل أسلوب عملي

إتقان اصطلاحات تسمية واجهات برمجة تطبيقات REST مع 10 قواعد عملية: أسماء الجمع، مسارات بصيغة kebab-case، تنسيق أحرف JSON، تحديد الإصدارات، والمعرفات. تتضمن أمثلة لما يجب فعله وما لا يجب فعله.

Ashley Goolam

Ashley Goolam

31 أغسطس 2026

قواعد تسمية REST API: دليل أسلوب عملي

Apidog للمؤسسات

النشر على الخوادم المحلية

SSO و RBAC

متوافق مع SOC 2

استكشف Apidog للمؤسسات

افتح أي قاعدة بيانات برمجية أقدم من سنتين وستجد الندوب: /getUser، /user_list، /Users/fetchAll، ثلاثة أنظمة ترقيم صفحات مختلفة، وحقل customerID بجوار order_id في نفس الاستجابة. لا شيء من هذا يكسر أي شيء. لكن كل ذلك يبطئ الجميع.

التسمية هي أرخص قرار تصميم واجهة برمجة تطبيقات (API) ستتخذه على الإطلاق والأكثر تكلفة في التراجع عنه. بمجرد أن تعتمد العملاء على /getOrders، ستكون ملزمًا بدعمها لسنوات. يقدم لك هذا الدليل قاعدة ملموسة لكل قرار تسمية تفرضه عليك واجهة برمجة تطبيقات REST، مع مثال ومثال مضاد لكل منها. إنه يتبع نفس التفكير في إرشاداتنا الأوسع لواجهة برمجة تطبيقات REST للمطورين، ولكنه يركز على الجزء الذي تتجادل فيه الفرق غالبًا: ما تسميه الأشياء.

إذا كنت تفضل فرض هذه القواعد باستخدام الأدوات بدلاً من تعليقات مراجعة الكود، فإن Apidog يتيح لك تحديد كل نقطة نهاية بصريًا مقابل مخطط مشترك قبل أن يكتب أي شخص سطرًا من الكود. المزيد عن ذلك في النهاية.

استخدم الأسماء الجمع للمجموعات

تحدد عناوين URL موردًا، وليس عملية. المجموعات هي مجموعات من الأشياء، لذا قم بتسميتها بأسماء الجمع.

افعل:

GET /v1/products
GET /v1/products/89
GET /v1/orders

لا تفعل:

GET /v1/getProducts
GET /v1/product
GET /v1/productList

يعمل صيغة الجمع على كلا المستويين. يُقرأ /products على أنه "مجموعة المنتجات" ويُقرأ /products/89 على أنه "المنتج 89 ضمن المجموعة". تفرض التسمية المفردة عناوين URL محرجة مثل /product/89 لعنصر واحد ولكن /product للعديد، مما يبدو خاطئًا. استقرت إرشادات واجهة برمجة تطبيقات REST من Microsoft على الأسماء الجمع لهذا السبب بالذات، واتبعت معظم واجهات برمجة التطبيقات العامة (Stripe، GitHub، Shopify) نفس المسار.

استثناء واحد: موارد المفردة (singleton). إذا كان لدى المستخدم عربة تسوق واحدة بالضبط، فإن /users/42/cart مقبول. لا تستخدم صيغة الجمع لشيء ذي عدد واحد.

ابقِ الأفعال خارج المسارات

طريقة HTTP هي الفعل. وضع فعل آخر في المسار يكرر المعلومات ويكسر نموذج المورد.

افعل:

GET    /v1/orders/42      (اقرأه)
DELETE /v1/orders/42      (احذفه)
PATCH  /v1/orders/42      (حدثه)

لا تفعل:

GET  /v1/fetchOrder/42
POST /v1/deleteOrder/42
POST /v1/updateOrderStatus

المسارات القائمة على الأفعال تزيد أيضًا من مساحة السطح الخاصة بك. يصبح المورد الواحد بأربع طرق أربع نقاط نهاية لتوثيقها واختبارها وتخزينها مؤقتًا بشكل منفصل. يصبح إلغاء صلاحية التخزين المؤقت أسوأ أيضًا: يمكن لشبكة توصيل المحتوى (CDN) تخزين GET /v1/orders/42 مؤقتًا وإلغاء صلاحيتها عند DELETE /v1/orders/42 لأن كلاهما يشير إلى نفس عنوان URL. لا يمكنها ربط /fetchOrder/42 بـ /deleteOrder/42.

استخدم kebab-case في مسارات URL

تحتاج مقاطع المسار المتعددة الكلمات إلى فاصل، والواصلات (hyphens) هي الفاصل الصحيح.

افعل:

/v1/gift-cards
/v1/shipping-addresses

لا تفعل:

/v1/giftCards
/v1/gift_cards
/v1/GiftCards

ثلاثة أسباب. تتعامل جوجل مع الواصلات كفواصل للكلمات لأغراض الفهرسة، لذا فإن وثائق API العامة تصنف بشكل أفضل باستخدام kebab-case. تختفي الشرطات السفلية (underscores) عندما يتم تسطير عنوان URL في رسالة بريد إلكتروني أو مستند. كما أن camelCase في عناوين URL يدعو إلى أخطاء حساسية حالة الأحرف: /giftCards و /giftcards هما عنوانان URL مختلفان على معظم الخوادم، وسيكتب شخص ما العنوان الخاطئ. تجعل إرشادات Zalando RESTful API من kebab-case قاعدة لا بد منها، وقد طبقوا هذا النهج عبر مئات الخدمات الداخلية.

اختر حالة كتابة JSON واحدة وقم بتوثيقها

بالنسبة لأسماء الحقول داخل نصوص الطلبات والاستجابات، الإجابة الصادقة هي: كل من camelCase و snake_case يعملان. ما لا يعمل هو مزجهما.

افعل (أحد الاثنين، باستمرار):

{ "orderId": 42, "createdAt": "2026-08-30T09:15:00Z", "totalAmount": 4999 }
{ "order_id": 42, "created_at": "2026-08-30T09:15:00Z", "total_amount": 4999 }

لا تفعل:

{ "orderId": 42, "created_at": "2026-08-30T09:15:00Z", "TotalAmount": 4999 }

يتطابق camelCase بسلاسة مع عملاء JavaScript و Java. أما snake_case فهو أسهل في الفحص ويتطابق مع أسماء أعمدة Ruby و Python ومعظم قواعد بيانات SQL؛ تستخدم Stripe هذا النمط في كل مكان. اختر بناءً على من يستهلك واجهة برمجة التطبيقات الخاصة بك أكثر، ثم ضع هذا الاختيار في دليل الأسلوب الخاص بك ليتم النقاش مرة واحدة بدلاً من كل طلب سحب. يعد استخدام حالات مختلفة في نفس الوقت التناقض الأكثر شيوعًا في واجهات برمجة التطبيقات الواقعية لأن الفرق المختلفة تقدم نقاط نهاية مختلفة. هذا فشل في الحوكمة، وليس فشلًا في الذوق.

حدّد التداخل بمستويين

يعبر التداخل عن الملكية: /users/42/orders يعني "الطلبات التي تخص المستخدم 42". هذا مفيد. بعد مستويين، يصبح غير مفيد.

افعل:

GET /v1/users/42/orders
GET /v1/orders/1337/refunds

لا تفعل:

GET /v1/users/42/orders/1337/refunds/7/status

التداخل العميق يجبر العملاء على حمل كل معرف للجد للوصول إلى مورد فرعي، حتى عندما يكون للمورد الفرعي معرف فريد عالميًا خاص به. إذا كان لاسترداد مبلغ معرف 7، اعرضه على /refunds/7 أو /orders/1337/refunds/7 وتوقف عند هذا الحد. اختبار بسيط: إذا كان عنوان URL يحتوي على ثلاثة معرفات أو أكثر، فقم بتبسيطه. بمجرد وجود طلب، لا يحتاج إلى المستخدم الخاص به في المسار؛ /orders/1337 يقف بمفرده.

ضع التصفية والفرز والتقسيم على صفحات في معلمات الاستعلام

تحدد المسارات الموارد. تعدل معلمات الاستعلام طريقة عرضها. لا تقم أبدًا بتضمين عامل تصفية في المسار.

افعل:

GET /v1/orders?status=active&sort=-created_at&limit=50&cursor=eyJpZCI6NDJ9
GET /v1/products?category=electronics&min_price=1000

لا تفعل:

GET /v1/orders/active
GET /v1/orders/sorted-by-date-desc
GET /v1/getOrdersByStatusAndDate

يأتي نمط sort=-created_at (بادئة ناقص لترتيب تنازلي) من مواصفات JSON:API ويوفر عليك معلمة ثانية order=desc. تبدو مسارات التصفية مثل /orders/active غير ضارة حتى تحتاج إلى دمج عوامل التصفية، وعندها ستنشئ نقطة نهاية جديدة لكل تركيبة. تستحق أسماء معلمات ترقيم الصفحات نفس الانضباط: اختر limit/cursor أو page/per_page مرة واحدة وأعد استخدامها في كل مجموعة. يغطي دليل ترقيم صفحات API الخاص بنا المقايضة بين المؤشر والإزاحة بعمق؛ قاعدة التسمية هنا هي ببساطة أن تكون موحدًا بشأنها.

الإصدار في المسار

لديك خياران رئيسيان: جزء من المسار (/v1/products) أو رأس (Accept: application/vnd.myapi.v1+json). يعتبر تحديد الإصدار في الرأس أكثر "نقاءً" من منظور REST، حيث يحافظ عنوان URL على تسمية نفس المورد عبر الإصدارات، وتلاحظ إرشادات تصميم API من Google أن كلا النهجين موجودان في الواقع. ولكن تحديد الإصدار في المسار يفوز من الناحية التشغيلية: فهو مرئي في كل سطر سجل، وقابل للاختبار من المتصفح، وقابل للتخزين المؤقت دون تعقيدات Vary، ومن المستحيل على العميل نسيانه. كل مطور قام بتصحيح مشكلة "يعمل في curl، ويفشل في الإنتاج" بسبب رأس إصدار مفقود يعرف تكلفة البديل. استخدم /v1/ مع إصدار رئيسي فقط، وليس /v1.2/؛ يجب أن تكون التغييرات الثانوية إضافية وغير مسببة للكسر. للحصول على شجرة القرار الكاملة، بما في ذلك تفاوض المحتوى، راجع مقارنتنا لـ استراتيجيات تحديد إصدار API.

تعامل مع معرفات الموارد كمعرفات مبهمة، ولا تسرب الأعداد الصحيحة المتسلسلة بإهمال

/orders/41، /orders/42، /orders/43: تخبر معرفات الأعداد الصحيحة المتسلسلة أي شخص ينظر إليها بالضبط عدد الطلبات التي تعالجها، وتدعو إلى هجمات التعداد حيث يقوم المهاجم بمسح مساحة المعرف بحثًا عن ثغرات في التفويض. هذه الفئة من الأخطاء، تفويض كائن المستوى المعطل، تحتل المرتبة الأولى في قائمة OWASP API Security Top 10.

افعل:

GET /v1/orders/ord_9f8e2a71b3
GET /v1/users/550e8400-e29b-41d4-a716-446655440000

لا تفعل (عندما يكون التعداد مهمًا):

GET /v1/orders/42
GET /v1/invoices/10883

تُعد المعرفات العشوائية المسبوقة مثل Stripe’s ord_9f8e2a71b3 هي النمط الأقوى: لا يمكن تخمينها، وتصف نفسها في السجلات، وآمنة للكشف عنها. لا تزال فحوصات التفويض إلزامية على أي حال. تقلل المعرفات المبهمة من نطاق تأثير الفحص المفقود؛ إنها لا تحل محله. داخليًا يمكنك الاحتفاظ بمفاتيح أساسية رقمية؛ القاعدة تتعلق بما تكشفه في عناوين URL.

نموذج الإجراءات غير CRUD كموارد تحكم

عاجلاً أم آجلاً، ستحتاج إلى إجراء ليس له تعيين CRUD واضح: إلغاء طلب، إعادة محاولة دفع، إعادة إرسال بريد إلكتروني. لا تمرره عبر PATCH على حقل حالة، ولا تضع فعلًا في المستوى الأعلى.

افعل:

POST /v1/orders/42/cancel
POST /v1/payments/pay_88a1/retry

لا تفعل:

PATCH /v1/orders/42        { "status": "cancelled" }
POST  /v1/cancelOrder      { "orderId": 42 }

هذا هو نمط المتحكم (controller pattern)، وهو الاستثناء الوحيد المسموح به لقاعدة عدم استخدام الأفعال: يذهب الفعل في نهاية المسار، ضمن نطاق المورد الذي يعمل عليه. يبدو أسلوب PATCH متوافقًا مع REST ولكنه يخفي آلة حالة داخل تحديث حقل. يؤدي إلغاء الطلب إلى استرداد الأموال، وتحرير المخزون، وإرسال إشعارات؛ التظاهر بأنه مجرد كتابة حقل يجبر خادمك على مقارنة الحمولات لاكتشاف النية. نقطة نهاية /cancel تحدد النية، وتمنح الإجراء أذوناته ومسار تدقيقه الخاص، وتترك مجالًا للمدخلات الخاصة بالإجراء مثل سبب الإلغاء.

حافظ على اتساق حالة الأحرف للرؤوس ومعلمات الاستعلام

سطحان أصغر، نفس الانضباط. تستخدم الرؤوس المخصصة Hyphenated-Pascal-Case، بما يتوافق مع اتفاقية HTTP: Idempotency-Key، Request-Id. تخطى البادئة القديمة X-؛ فقد تم إهمالها بموجب RFC 6648 في عام 2012. أسماء الرؤوس غير حساسة لحالة الأحرف على الشبكة، ولكن يجب أن تقوم وثائقك ومجموعات تطوير البرامج (SDKs) بكتابتها بطريقة واحدة.

يجب أن تتطابق معلمات الاستعلام مع حالة كتابة نص JSON الخاص بك. إذا كانت نصوصك تستخدم snake_case، فاكتب ?min_price=1000&created_after=2026-01-01، وليس ?minPrice=1000. المطور الذي يقرأ created_at في استجابة ويجب عليه كتابة createdAfter في استعلام سيخطئ في المحاولة الأولى، وكذلك سيفعل كل من يأتي بعده.

نظرة سريعة على مجموعة القواعد الكاملة

# القاعدة افعل لا تفعل
1 أسماء الجمع للمجموعات /products, /products/89 /getProducts, /productList
2 لا أفعال في المسارات DELETE /orders/42 POST /deleteOrder/42
3 مقاطع المسار بنمط kebab-case /gift-cards /giftCards, /gift_cards
4 حالة كتابة JSON واحدة وموثقة order_id في كل مكان مزيج من orderId و order_id
5 مستويان كحد أقصى للتداخل /orders/1337/refunds /users/42/orders/1337/refunds/7
6 عوامل التصفية والتقسيم على صفحات في معلمات الاستعلام ?status=active&sort=-created_at /orders/active
7 الإصدار الرئيسي في المسار /v1/products /v1.2/products, رؤوس الإصدار
8 معرفات الموارد المبهمة /orders/ord_9f8e2a71b3 /orders/42 (عام، قابل للتعداد)
9 نمط المتحكم للإجراءات POST /orders/42/cancel PATCH مع {"status":"cancelled"}
10 اتساق حالة الأحرف للرأس والمعلمة Idempotency-Key, ?min_price= مزيج من X-IDEMPOTENCY_KEY, ?minPrice=

فرض الاتفاقيات على نطاق واسع

دليل الأسلوب في الويكي لا يغير شيئًا. الفرق التي تحافظ واجهات برمجة تطبيقاتها على الاتساق تشترك في عادة واحدة: أنها تصمم أولاً وتفرض الاتفاقيات قبل وجود الكود، وهو جوهر حوكمة API في الممارسة العملية.

هنا يكتسب Apidog مكانته في سير العمل. يتم تعريف نقاط النهاية في مصمم مرئي يعتمد على المخطط أولاً، بحيث تكون أسماء المسارات وحالات الأحرف والمعلمات عناصر تصميم صريحة بدلاً من سلاسل مدفونة في كود المتحكم (controller). تعني المكونات المشتركة أن مخططات Pagination و Error و Money يتم تعريفها مرة واحدة وإعادة استخدامها عبر كل نقطة نهاية؛ لا يقوم أحد بإعادة اختراع per_page كـ pageSize على خدمة جديدة. ولأن التصميمات تعيش في مساحات عمل الفرق مع مراجعة مدمجة، يمكن للمسؤول اكتشاف /getUserOrders في وقت التصميم، عندما لا يكلف إعادة التسمية سوى نقرة واحدة، بدلاً من بعد دمج ثلاثة عملاء معها. ثم يدفع المواصفات الوثائق والخوادم الوهمية والاختبارات، بحيث تكون الأسماء التي وافقت عليها هي الأسماء التي يشحنها الجميع. قم بتنزيل Apidog وجربه مجانًا مع نقطة النهاية الجديدة التالية؛ تحديث واجهة برمجة تطبيقات قديمة صعب، ولكن الحفاظ على المعايير في الواجهات الجديدة ليس كذلك.

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

هل يجب أن تكون عناوين URL في REST بصيغة الجمع أم المفرد؟

بصيغة الجمع، لأي مورد يحتوي على أكثر من مثيل واحد: /products، /orders، /users. تظل صيغة الجمع طبيعية لكل من المجموعة (/orders) وعضو واحد (/orders/42). احتفظ بأسماء المفرد للمفردات الحقيقية مثل /users/42/cart. إذا كنت تريد التعمق في الأسباب الكامنة وراء نمذجة الموارد، فإن دليلنا حول ما هي واجهة برمجة تطبيقات REST يشرح ذلك من المبادئ الأساسية.

هل camelCase أم snake_case أفضل لأسماء حقول JSON؟

لا يفوز أي منهما بناءً على الأفضلية المطلقة. يناسب camelCase المستهلكين الذين يعتمدون بشكل كبير على JavaScript؛ بينما snake_case أكثر قابلية للقراءة ويتطابق مع Python و Ruby وواجهة برمجة تطبيقات Stripe العامة. القاعدة الحاسمة: اختر واحدًا، واكتبه في دليل الأسلوب الخاص بك، وافرضه في مراجعة المخطط. استخدام حالات مختلطة عبر نقاط النهاية يضر أكثر من أي من الخيارين.

هل يجب أن أضع إصدار API في عنوان URL أو في الرأس؟

استخدم المسار (/v1/orders) إلا إذا كان لديك متطلب قوي للوسائط التشعبية. تظهر إصدارات المسار في السجلات، وذاكرات التخزين المؤقت، واختبارات المتصفح بدون أي جهد من العميل. يحافظ تحديد الإصدار في الرأس على استقرار عناوين URL عبر الإصدارات ولكنه يفشل بصمت عندما ينسى العملاء الرأس. إصدارات رئيسية فقط؛ قم بشحن التغييرات الثانوية كتحديثات إضافية وغير مسببة للكسر.

هل الأفعال مقبولة في مسار REST API على الإطلاق؟

نعم، في مكان واحد: نقاط نهاية المتحكم (controller endpoints) للإجراءات غير CRUD، مثل POST /orders/42/cancel أو POST /payments/pay_88a1/retry. يقع الفعل في نهاية المسار، ضمن نطاق المورد الذي يعمل عليه، وتكون الطريقة دائمًا POST. في أي مكان آخر، تحمل طريقة HTTP الفعل ويبقى المسار أسماء فقط.

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات