web services - فهم REST: الأفعال ، رموز الخطأ ، والمصادقة




web-services (7)

أساسيات REST

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

لذلك هناك عقد بين عميل REST وخدمة REST. إذا كنت تستخدم HTTP كبروتوكول أساسي ، فستكون المعايير التالية جزءًا من العقد:

  • HTTP 1.1
    • تعريفات الطريقة
    • تعريفات رمز الحالة
    • عناوين التحكم في ذاكرة التخزين المؤقت
    • قبول ورأس نوع المحتوى
    • عناوين المصادقة
  • IRI (utf8 URI )
  • الجسم (اختر واحدة)
    • نوع MIME للتطبيق المسجل ، على سبيل المثال maze+xml
    • نوع MIME خاص ببائع ، على سبيل المثال vnd.github+json
    • نوع MIME عام مع
      • تطبيق معين RDF vocab ، على سبيل المثال ld+json & hydra ، schema.org
      • ملف تعريف معين ، على سبيل المثال ، hal+json & link profile param (على ما أظن)
  • وصلات
    • ما الذي يجب أن يحتوي عليها (اختر واحدة)
      • إرسال رؤوس الروابط
      • إرسال استجابة hypermedia ، مثل html و atom + xml و hal + json و ld + json & hydra وغيرها ...
    • دلالات
      • استخدام علاقات ارتباط IANA وربما علاقات الارتباط المخصصة
      • استخدام تطبيق معين vocab RDF

لدى REST قيد بدون حالة ، الذي ينص على أن الاتصال بين خدمة REST والعميل يجب أن يكون عديم الحالة. هذا يعني أن خدمة REST لا يمكنها الحفاظ على حالات العميل ، لذلك لا يمكنك الحصول على وحدة تخزين جانب الملقم. لديك لمصادقة كل طلب واحد. لذلك ، على سبيل المثال ، يكون بروتوكول HTTP الأساسي (جزء من معيار HTTP) مقبولًا ، لأنه يرسل اسم المستخدم وكلمة المرور مع كل طلب.

للإجابة عليك الأسئلة

  1. نعم يمكن أن يكون.

    على سبيل المثال ، العملاء لا يهتمون بهيكل IRI ، فهم يهتمون بالدلالات ، لأنهم يتابعون الروابط التي لها علاقات ارتباط أو بيانات مرتبطة (RDF).

    الشيء الوحيد المهم حول IRIs ، أن IRI واحد يجب أن يحدد فقط مورد واحد. يسمح لمورد واحد ، مثل مستخدم ، بالحصول على العديد من IRI مختلفة.

    انها بسيطة جدا لماذا نستخدم IRIs لطيفة مثل /users/123/password . من الأسهل بكثير كتابة منطق التوجيه على الخادم عند فهم IRI ببساطة عن طريق قراءته.

  2. لديك المزيد من الأفعال ، مثل PUT ، PATCH ، OPTIONS ، وأكثر من ذلك ، ولكنك لا تحتاج إلى المزيد منها ... بدلاً من إضافة أفعال جديدة عليك تعلم كيفية إضافة موارد جديدة.

    activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}

    (لا معنى للدخول من منظور REST ، بسبب القيد عديمة الحالة.)

  3. المستخدمون لا يهتمون بمعرفة سبب وجود المشكلة. فهم يريدون فقط معرفة ما إذا كان هناك نجاح أو خطأ ، وربما رسالة خطأ يمكنهم فهمها ، على سبيل المثال: "عذرًا ، لكننا لم نتمكن من حفظ مشاركتك" ، وما إلى ذلك ...

    تعد رؤوس حالة HTTP هي الرؤوس القياسية. كل شيء آخر يجب أن يكون في الجسم على ما أعتقد. رأس واحد لا يكفي لوصف على سبيل المثال رسائل خطأ متعددة اللغات مفصلة.

  4. يضمن القيد عديمة الحالة (مع قيود ذاكرة التخزين المؤقت ونظام الطبقات) أن تكون الخدمة جيدة. أنت بالتأكيد لا ترغب في الحفاظ على الملايين من الجلسات على الخادم ، عندما يمكنك أن تفعل الشيء نفسه على العملاء ...

    يحصل عميل الطرف الثالث على رمز وصول إذا منح المستخدم حق الوصول إليه باستخدام العميل الرئيسي. بعد ذلك يرسل عميل الطرف الثالث رمز الدخول مع كل طلب. هناك حلول أكثر تعقيدًا ، على سبيل المثال ، يمكنك توقيع كل طلب ، وما إلى ذلك. لمزيد من التفاصيل ، راجع دليل OAuth.

الأدبيات ذات الصلة

أنا أبحث عن طريقة لبرمجة واجهات برمجة التطبيقات حول الوظائف الافتراضية في تطبيقات الويب وقواعد البيانات و CMS.

لقد نظرت حولي ووجدت العديد من أطر "الهيكل العظمي". بالإضافة إلى الإجابات في سؤالي ، هناك Tonic ، وهو إطار REST أحب لأنه خفيف جدا.

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

1. هل أنا أفهم ذلك صحيح؟

قل لدي مورد "المستخدمين". يمكنني إعداد عدد من عناوين URI على النحو التالي:

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user record
               when called with PUT, updates user record
               when called with DELETE, deletes user record

هل هذا تمثيل صحيح لعمارة RESTful حتى الآن؟

2. أحتاج المزيد من الأفعال

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

بعض ما يتبادر إلى الذهن في مثال المستخدم هي:

activate_login
deactivate_login
change_password
add_credit

كيف أعبّر عن إجراءات مثل تلك الموجودة في بنية RESTful URL؟

ستكون غريزتي هي إجراء مكالمة GET إلى عنوان URL مثل

/api/users/1/activate_login 

وتوقع رمز الحالة مرة أخرى.

هذا ينحرف عن فكرة استخدام أفعال HTTP ، رغم ذلك. ما رأيك؟

3. كيفية إرجاع رسائل الخطأ والرموز

ينبع جزء كبير من جمال REST من استخدامه لطرق HTTP القياسية. على خطأ ، أبعث رأس مع رمز حالة خطأ 3xx أو 4xx أو 5xx. للحصول على وصف تفصيلي للخطأ ، يمكنني استخدام النص (صحيح؟). حتى الان جيدة جدا. ولكن ما هي الطريقة لنقل رمز خطأ خاص بالملكية أكثر تفصيلاً في وصف الخطأ الذي حدث (مثل "فشل الاتصال بقاعدة البيانات" ، أو "تسجيل الدخول إلى قاعدة بيانات خاطئة")؟ إذا وضعت في الجسم مع الرسالة ، لا بد لي من تحليلها بعد ذلك. هل هناك عنوان قياسي لهذا النوع من الأشياء؟

4. كيف نفعل المصادقة

  • كيف تبدو مصادقة أساس واجهة برمجة التطبيقات التي تتبع مبادئ REST؟
  • هل هناك نقاط قوية ضد استخدام الجلسات عند مصادقة عميل REST ، بخلاف أنه انتهاك صارخ لمبدأ REST؟ :) (فقط نصف المزاح هنا ، المصادقة المستندة إلى الجلسات ستلعب بشكل جيد مع البنية التحتية الحالية.)

  1. استخدم النشر عندما لا تعرف كيف سيبدو URI المورد الجديد (تقوم بإنشاء مستخدم جديد ، سيقوم التطبيق بتعيين المستخدم الجديد له) ، PUT لتحديث أو إنشاء موارد تعرف كيف سيتم تمثيلها (مثال : PUT /myfiles/thisismynewfile.txt)
  2. إرجاع وصف الخطأ في نص الرسالة
  3. يمكنك استخدام مصادقة HTTP (إذا كانت كافية) يجب أن تكون خدمات الويب stateles

ببساطة ، أنت تفعل هذا إلى الوراء بالكامل.

يجب ألا تقترب من عناوين URL التي يجب أن تستخدمها. ستأتي عناوين URL بشكل فعال "مجانًا" بمجرد تحديد الموارد اللازمة لنظامك وكيف ستُمثّل هذه الموارد والتفاعلات بين الموارد وحالة التطبيق.

اقتبس روي فيلدينغ

يجب أن تقضي واجهة برمجة التطبيقات (REST API) تقريبًا كل جهدها الوصفي في تعريف نوع (أنواع) الوسائط المستخدمة في تمثيل الموارد ودالة التطبيق ، أو في تعريف أسماء العلاقات الموسعة و / أو ترميز تمكين النص التشعبي لأنواع الوسائط القياسية الحالية. أي جهد يتم بذله لوصف الطرق المستخدمة في ما يتعلق بـ URIs ذات الأهمية يجب أن يتم تعريفها بالكامل في نطاق قواعد المعالجة لنوع الوسائط (وفي معظم الحالات ، تم تعريفها بالفعل بواسطة أنواع الوسائط الموجودة). [الفشل هنا يعني أن المعلومات خارج النطاق تقود التفاعل بدلاً من النص التشعبي.]

يبدأ الناس دائمًا بـ URIs ويعتقدون أن هذا هو الحل ، ثم يميلون إلى فقدان المفهوم الأساسي في بنية REST ، بشكل خاص ، كما هو موضح أعلاه ، "الفشل هنا يعني أن المعلومات خارج النطاق تدفع إلى التفاعل بدلاً من النص التشعبي. "

لنكون صادقين ، يرى العديد من حفنة من URIs وبعض GETs و PUTs و POSTs واعتقد REST أمر سهل. REST ليست سهلة. يعد RPC عبر HTTP أمرًا سهلاً ، حيث يسهل نقل النقط من البيانات ذهابًا وإيابًا عبر البروتوكولات عبر HTTP. REST ، ومع ذلك ، يتجاوز ذلك. REST هو بروتوكول الملحد. HTTP هو مجرد شعبية جدا وملائم لأنظمة REST.

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

هناك وجهة نظر مختلفة حول أنواع الوسائط في أنظمة REST. يفضل البعض استخدام الحمولات الصافية الخاصة بالتطبيقات ، بينما يحبذ البعض الآخر رفع أنواع الوسائط الموجودة إلى الأدوار المناسبة للتطبيق. على سبيل المثال ، من ناحية ، لديك مخططات XML محددة مصممة لتناسب تطبيقك مقابل استخدام شيء مثل XHTML كتصميمك ، ربما من خلال تنسيقات microformat والآليات الأخرى.

كلتا الطريقتين لديهما مكانهما ، كما أعتقد ، أن لغة XHTML تعمل جيدًا في السيناريوهات التي تتداخل مع كلٍّ من الويب المدفوع بالأنسان والمدفوعة بالآلات ، في حين أن أنواع البيانات السابقة والأكثر تحديدًا التي أشعر أنها تسهل التفاعل بين الماكينات والآلات بشكل أفضل. أجد أن الارتقاء بصيغ السلع الأساسية يمكن أن يجعل التفاوض على المحتوى أمرًا صعبًا. "application / xml + yourresource" أكثر تحديدًا كنوع وسائط أكثر من "application / xhtml + xml" ، حيث يمكن أن ينطبق هذا الأخير على العديد من الحمولات التي قد تكون أو لا تكون شيئًا ما يهتم به العميل الآلي ، ولا تحديد دون الاستبطان.

ومع ذلك ، يعمل XHTML بشكل جيد (بشكل واضح) في شبكة الإنترنت حيث تكون متصفحات الويب والتقديم مهمة للغاية.

سوف يرشدك التطبيق في مثل هذه القرارات.

جزء من عملية تصميم نظام REST هو اكتشاف موارد الطبقة الأولى في النظام الخاص بك ، جنبا إلى جنب مع مشتقات وموارد الدعم اللازمة لدعم العمليات على الموارد الأولية. بمجرد اكتشاف الموارد ، ثم تمثيل تلك الموارد ، فضلا عن الرسوم البيانية للدولة تبين تدفق الموارد عبر النص التشعبي داخل التمثيلات بسبب التحدي التالي.

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

على سبيل المثال ، قد يكون لديك:

<link href="http://example.com/users" rel="users" type="application/xml+usercollection"/>
<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>

ستتحدث وثائقك عن حقل rel بعنوان "users" ، ونوع الوسائط "application / xml + youruser".

قد تبدو هذه الوصلات زائدة عن الحاجة ، وكلها تتحدث إلى نفس URI ، إلى حد كبير. لكنهم ليسوا كذلك.

هذا لأن علاقة "المستخدمين" ، هذا الارتباط يتحدث عن مجموعة المستخدمين ، ويمكنك استخدام واجهة موحدة للعمل مع المجموعة (GET لاسترداد كل منهم ، DELETE لحذف كل منهم ، وما إلى ذلك)

إذا كنت POST إلى عنوان URL هذا ، فستحتاج إلى تمرير مستند "application / xml + usercollection" ، والذي قد يحتوي فقط على نسخة مستخدم واحدة داخل المستند حتى تتمكن من إضافة المستخدم ، أو ربما ، لإضافة عدة مستخدمين على ذات مرة. ربما تقترح وثائقك أنه يمكنك ببساطة تمرير نوع مستخدم واحد ، بدلاً من المجموعة.

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

ومع ذلك ، فإن الوجبات الجاهزة هنا هي أن عناوين URI نفسها غير مهمة في الأساس. التطبيق هو السيطرة على URIs ، وليس للعملاء. أبعد من "نقاط دخول" قليلة ، يجب أن يعتمد عملاؤك على عناوين URI المقدمة من قبل التطبيق لعملها.

يحتاج العميل إلى معرفة كيفية التعامل مع أنواع الوسائط وتفسيرها ، ولكنه لا يحتاج إلى رعاية أين تذهب.

هذان الرابطان متطابقان دلاليًا في نظر العملاء:

<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>
<link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/>

لذلك ، ركز على مواردك. ركز على تحولات الحالة في التطبيق وكيفية تحقيق ذلك على أكمل وجه.


لقد لاحظت هذا السؤال متأخراً بضعة أيام ، لكني أشعر أنه يمكنني إضافة بعض الأفكار. آمل أن يكون هذا مفيدًا في مشروع RESTful.

النقطة 1: هل أفهمها بشكل صحيح؟

أنت فهمت الحق. هذا هو تمثيل صحيح لبنية RESTful. قد تجد المصفوفة التالية من Wikipedia مفيدة جدا في تحديد الأسماء والأفعال الخاصة بك:

عند التعامل مع معرف URI لمجموعة ، مثل: http://example.com/resources/

  • الحصول على : قائمة أعضاء المجموعة ، كاملة مع URIs الأعضاء الخاصة بهم لمزيد من الملاحة. على سبيل المثال ، قائمة بجميع السيارات المعروضة للبيع.

  • PUT : المعنى المعرّف بأنه "استبدال المجموعة بأكملها بمجموعة أخرى".

  • POST : قم بإنشاء إدخال جديد في المجموعة حيث يتم تعيين المعرف تلقائيًا بواسطة المجموعة. عادة ما يتم تضمين المعرف الذي تم إنشاؤه كجزء من البيانات التي يتم إرجاعها من خلال هذه العملية.

  • الحذف : المعنى المعرّف على أنه "حذف المجموعة بأكملها".

عند التعامل مع URI عضو مثل: http://example.com/resources/7HOU57Y

  • GET : استرداد تمثيل العضو المعنون في المجموعة معبرا في نوع MIME مناسب.

  • PUT : تحديث العضو المعني في المجموعة أو إنشائه بالمعرف المحدد.

  • POST : يعامل العضو المعنون كمجموعة في حد ذاته ويخلق فرعية جديدة منه.

  • الحذف : حذف العضو المعنون من المجموعة.

النقطة 2: أحتاج إلى المزيد من الأفعال

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

تنشيط / إلغاء تنشيط تسجيل الدخول : إذا كنت تقوم بإنشاء جلسة عمل جديدة ، فقد ترغب في اعتبار "جلسة العمل" بمثابة المورد. لإنشاء جلسة جديدة ، استخدم POST إلى http://example.com/sessions/ باستخدام بيانات الاعتماد في النص الأساسي. لتنتهي صلاحيتها ، استخدم PUT أو DELETE (ربما بناءً على ما إذا كنت تنوي الاحتفاظ بسجل جلسة) إلى http://example.com/sessions/SESSION_ID .

تغيير كلمة المرور: هذه المرة المورد "المستخدم". ستحتاج إلى PUT إلى http://example.com/users/USER_ID باستخدام كلمات المرور القديمة والجديدة في النص الأساسي. أنت تتصرف على مورد "المستخدم" ، وكلمة مرور التغيير هي مجرد طلب تحديث. تشبه إلى حد بعيد عبارة UPDATE في قاعدة بيانات علائقية.

ستكون غريزتي هي إجراء مكالمة GET إلى عنوان URL مثل /api/users/1/activate_login

يتعارض هذا مع مبدأ REST الأساسي: الاستخدام الصحيح لأفعال HTTP. يجب ألا يترك أي طلب GET أي أثر جانبي.

على سبيل المثال ، يجب ألا يقوم طلب GET بإنشاء جلسة عمل على قاعدة البيانات ، أو إرجاع ملف تعريف ارتباط بمعرف جلسة عمل جديد ، أو ترك أي رواسب على الخادم. يشبه الفعل GET عبارة SELECT في مشغل قاعدة بيانات. تذكر أن الاستجابة لأي طلب باستخدام فعل GET يجب أن تكون قابلة للتخزين المؤقت عند طلبها باستخدام نفس المعلمات ، تمامًا كما يحدث عند طلب صفحة ويب ثابتة.

النقطة 3: كيفية إرجاع رسائل الخطأ والرموز

ضع في اعتبارك رموز الحالة HTTP 4xx أو 5xx كفئات خطأ. يمكنك وضع الخطأ في الجسم.

فشل الاتصال بقاعدة البيانات: / تسجيل الدخول إلى قاعدة البيانات غير الصحيحة : بشكل عام ، يجب استخدام خطأ 500 لهذه الأنواع من الأخطاء. هذا خطأ من جانب الخادم. العميل لم يفعل شيئا خطأ. 500 أخطاء تعتبر عادة "إعادة المحاولة". أي يمكن للعميل إعادة طلب نفس الطلب بالضبط ، ونتوقع أن ينجح بمجرد حل مشاكل الخادم. حدد التفاصيل في النص الأساسي ، حتى يتمكن العميل من توفير بعض السياق لنا.

الفئة الأخرى من الأخطاء هي عائلة 4xx ، والتي تشير بشكل عام إلى أن العميل قام بشيء خاطئ. على وجه الخصوص ، تشير هذه الفئة من الأخطاء عادة إلى العميل أنه لا توجد حاجة لإعادة الطلب كما هو ، لأنه سيستمر بالفشل بشكل دائم. أي يحتاج العميل إلى تغيير شيء ما قبل إعادة محاولة هذا الطلب. على سبيل المثال ، قد تقع أخطاء "المورد غير موجود" (HTTP 404) أو "طلب غير صحيح" (HTTP 400) في هذه الفئة.

النقطة 4: كيفية القيام بالمصادقة

كما أشرنا في النقطة 1 ، بدلاً من مصادقة مستخدم ، قد ترغب في التفكير في إنشاء جلسة عمل. سيتم إرجاع "معرف جلسة" جديد ، بالإضافة إلى رمز حالة HTTP المناسب (200: Access Granted or 403: Access Denied).

ستقوم حينئذٍ بسؤال خادم RESTful: "هل يمكنك الحصول على الموارد لمعرف الجلسة هذا؟".

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


مطول ، ولكن تم نسخها من مواصفات أسلوب HTTP 1.1 على http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9.3 الحصول على

تعني طريقة GET استرجاع أي معلومات (في شكل كيان) يتم تحديدها من خلال طلب URI. إذا كان طلب-URI يشير إلى عملية إنتاج البيانات ، فإنه يتم إنتاج البيانات التي سيتم إرجاعها ككيان في الاستجابة وليس النص المصدر للعملية ، ما لم يحدث ذلك أن يكون النص الناتج عن العملية.

تتغير دلالات طريقة GET إلى "GET شرطي" إذا كانت رسالة الطلب تتضمن If-Modified-Since أو If-Unmodified-Since أو If-Match أو If-None-Match أو حقل رأس If-Range. تطلب طريقة GET المشروطة نقل الكيان فقط في ظل الظروف الموضحة في حقل (حقول) الرأس المشروطة. يهدف أسلوب GET الشرطي إلى تقليل استخدام الشبكة غير الضروري من خلال السماح بالتحديث إلى العناصر المخزنة مؤقتًا دون الحاجة إلى طلبات متعددة أو نقل البيانات الموجودة بالفعل لدى العميل.

تتغير دلالات طريقة GET إلى "GET جزئي" إذا كانت رسالة الطلب تتضمن حقل رأس نطاق. تطلب طلبات GET جزئية نقل جزء من الكيان فقط ، كما هو موضح في القسم 14.35. تهدف طريقة GET الجزئية إلى تقليل استخدام الشبكة غير الضروري من خلال السماح باستكمال الكيانات التي تم استردادها جزئيًا دون نقل البيانات الموجودة بالفعل لدى العميل.

تكون الاستجابة لطلب GET قابلة للتخزين المؤقت فقط إذا كانت تفي بمتطلبات التخزين المؤقت لـ HTTP الموضح في القسم 13.

انظر القسم 15.1.3 لاعتبارات الأمان عند استخدامها للنماذج.

9.5 وظيفة

تُستخدم طريقة POST لطلب أن يقبل خادم الأصل الكيان المضمن في الطلب كجهة فرعية جديدة من الموارد المحددة بواسطة طلب-URI في سطر الطلب. تم تصميم POST للسماح بطريقة موحدة لتغطية الوظائف التالية:

  - Annotation of existing resources;
  - Posting a message to a bulletin board, newsgroup, mailing list,
    or similar group of articles;
  - Providing a block of data, such as the result of submitting a
    form, to a data-handling process;
  - Extending a database through an append operation.

يتم تحديد الوظيفة الفعلية التي يتم تنفيذها بواسطة طريقة POST بواسطة الخادم وعادةً ما تعتمد على طلب-URI. يكون الكيان المنشور مرتبطًا بـ URI بنفس الطريقة التي يخضع بها الملف إلى دليل يحتوي عليه ، أو مقالة إخبارية تابعة لمجموعة أخبار يتم نشرها ، أو أن السجل يخضع لقاعدة بيانات.

قد لا يؤدي الإجراء الذي يتم تنفيذه بواسطة أسلوب POST إلى مورد يمكن تعريفه بواسطة معرف موارد منتظم. في هذه الحالة ، إما 200 (OK) أو 204 (لا يوجد محتوى) هي حالة الاستجابة المناسبة ، اعتمادًا على ما إذا كانت الاستجابة تتضمن كيانًا يصف النتيجة أم لا.

إذا تم إنشاء مورد على خادم المصدر ، يجب أن تكون الاستجابة 201 (تم الإنشاء) وتحتوي على كيان يصف حالة الطلب ويشير إلى المورد الجديد ورأسية الموقع (انظر القسم 14.30).

الردود على هذه الطريقة غير قابلة للتخزين المؤقت ، ما لم تتضمن الاستجابة حقول رأسية Cache-Control أو Expires مناسبة. ومع ذلك ، يمكن استخدام استجابة 303 (انظر غير ذلك) لتوجيه وكيل المستخدم لاسترداد مورد قابل للتخزين المؤقت.

يجب أن تخضع طلبات POST لمتطلبات إرسال الرسائل المنصوص عليها في القسم 8.2.

انظر القسم 15.1.3 لاعتبارات الأمان.

9.6

تطلب طريقة PUT أن يتم تخزين الكيان المرفق تحت عنوان URI المطلوب. إذا كان Request-URI يشير إلى مورد موجود بالفعل ، فيجب اعتبار الكيان المرفق كإصدار معدل للواحد المقيم على خادم المصدر. إذا لم يوجه طلب-URI إلى مورد موجود ، وأن معرف URI قادر على أن يتم تعريفه كمورد جديد بواسطة وكيل المستخدم المطالب ، يمكن لخادم الأصل إنشاء المورد باستخدام ذلك URI. إذا تم إنشاء مورد جديد ، فيجب على خادم المصدر إعلام وكيل المستخدم عبر استجابة 201 (تم الإنشاء). إذا تم تعديل مورد موجود ، فيجب إرسال رمز الاستجابة 200 (OK) أو 204 (بدون محتوى) للإشارة إلى إكمال الطلب بنجاح. If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. The recipient of the entity MUST NOT ignore any Content-* (eg Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI,

it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.

A single resource MAY be identified by many different URIs. For example, an article might have a URI for identifying "the current version" which is separate from the URI identifying each particular version. In this case, a PUT request on a general URI might result in several other URIs being defined by the origin server.

HTTP/1.1 does not define how a PUT method affects the state of an origin server.

PUT requests MUST obey the message transmission requirements set out in section 8.2.

Unless otherwise specified for a particular entity-header, the entity-headers in the PUT request SHOULD be applied to the resource created or modified by the PUT.

9.7 DELETE

The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location.

A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.


1. كنت قد حصلت على الفكرة الصحيحة حول كيفية تصميم الموارد الخاصة بك ، IMHO. لن أغير شيئًا.

2. بدلاً من محاولة توسيع نطاق HTTP بأكثر الأفعال ، فكر في ما يمكن تقليله من أفعالك المقترحة من حيث أساليب وموارد HTTP الأساسية. على سبيل المثال ، بدلاً من الفعل activate_login ، يمكنك إعداد موارد مثل: /api/users/1/login/active وهو منطقي بسيط. لتنشيط تسجيل دخول ، فقط PUT مستندًا هناك "صحيح" أو 1 أو أيًا كان. لإلغاء التنشيط ، PUT مستندًا فارغًا أو يقول 0 أو خطأ.

وبالمثل ، لتغيير أو تعيين كلمات المرور ، قم فقط بـ PUT s إلى /api/users/1/password .

كلما كنت بحاجة إلى إضافة شيء ما (مثل الائتمان) فكر في شروط POST s. على سبيل المثال ، يمكنك إجراء POST إلى مورد مثل /api/users/1/credits مع هيئة تحتوي على عدد الأرصدة المراد إضافتها. يمكن استخدام PUT على نفس المورد للكتابة فوق القيمة بدلاً من إضافة. سيتم طرح POST مع رقم سالب في الجسم ، وهكذا.

3. أنصح بشدة بعدم تمديد رموز حالة HTTP الأساسية. إذا لم تتمكن من العثور على واحد يطابق حالتك تمامًا ، فاختر أقرب واحد منك وضع تفاصيل الخطأ في نص الاستجابة. وتذكر أيضًا أن رؤوس HTTP قابلة للتوسعة ؛ يمكن للتطبيق تحديد جميع العناوين المخصصة التي تعجبك. أحد التطبيقات التي عملت عليها ، على سبيل المثال ، يمكن أن يعرض 404 Not Found تحت ظروف متعددة. بدلاً من جعل العميل يقوم بتحليل هيئة الاستجابة للسبب ، قمنا فقط بإضافة رأس جديد ، X-Status-Extended ، والذي يحتوي على امتدادات كود الحالة الخاصة بنا. لذلك قد ترى استجابة مثل:

HTTP/1.1 404 Not Found    
X-Status-Extended: 404.3 More Specific Error Here

وبهذه الطريقة ، سيظل عميل HTTP مثل متصفح الويب يعرف ما يجب فعله باستخدام رمز 404 العادي ، ويمكن لعميل HTTP أكثر تطوراً أن يختار عرض رأس X-Status-Extended لمزيد من المعلومات المحددة.

4. للمصادقة ، أوصي باستخدام مصادقة HTTP إذا استطعت. ولكن IMHO لا يوجد شيء خاطئ في استخدام المصادقة المستندة إلى ملفات تعريف الارتباط إذا كان ذلك أسهل بالنسبة لك.


About REST return codes: it is wrong to mix HTTP protocol codes and REST results.

However, I saw many implementations mixing them, and many developers may not agree with me.

HTTP return codes are related to the HTTP Request itself. A REST call is done using a Hypertext Transfer Protocol request and it works at a lower level than invoked REST method itself. REST is a concept/approach, and its output is a business/logical result, while HTTP result code is a transport one.

For example, returning "404 Not found" when you call /users/ is confuse, because it may mean:

  • URI is wrong (HTTP)
  • No users are found (REST)

"403 Forbidden/Access Denied" may mean:

  • Special permission needed. Browsers can handle it by asking the user/password. (HTTP)
  • Wrong access permissions configured on the server. (HTTP)
  • You need to be authenticated (REST)

And the list may continue with '500 Server error" (an Apache/Nginx HTTP thrown error or a business constraint error in REST) or other HTTP errors etc...

From the code, it's hard to understand what was the failure reason, a HTTP (transport) failure or a REST (logical) failure.

If the HTTP request physically was performed successfully it should always return 200 code, regardless is the record(s) found or not. Because URI resource is found and was handled by the http server. Yes, it may return an empty set. Is it possible to receive an empty web-page with 200 as http result, right?

Instead of this you may return 200 HTTP code and simply a JSON with an empty array/object, or to use a bool result/success flag to inform about the performed operation status.

Also, some internet providers may intercept your requests and return you a 404 http code. This does not means that your data are not found, but it's something wrong at transport level.

From Wiki :

In July 2004, the UK telecom provider BT Group deployed the Cleanfeed content blocking system, which returns a 404 error to any request for content identified as potentially illegal by the Internet Watch Foundation. Other ISPs return a HTTP 403 "forbidden" error in the same circumstances. The practice of employing fake 404 errors as a means to conceal censorship has also been reported in Thailand and Tunisia. In Tunisia, where censorship was severe before the 2011 revolution, people became aware of the nature of the fake 404 errors and created an imaginary character named "Ammar 404" who represents "the invisible censor".





rest