REST, HTTP DELETE та параметри


135

Чи є щось непогашене у наданні параметрів для HTTP DELETE-запиту?


Мій сценарій полягає в тому, що я моделюю "Ви впевнені, що хочете видалити це?" сценарій. У деяких випадках стан ресурсу говорить про те, що запитуване видалення може бути недійсним. Ви, напевно, можете собі уявити деякі сценарії, де потрібно підтвердження видалення

Ми прийняли рішення - передати параметр запиту на видалення, щоб вказати, що нормально продовжувати видалення ("? Force_delete = true")

напр

DELETE http://server/resource/id?force_delete=true

Я вважаю, що все ще спокійно:

(a) Семантика DELETE не змінюється - користувач може все-таки надіслати звичайний DELETE-запит, але це може бути невдалим із номером 409, і тіло відповіді пояснить, чому. Я кажу, що це може бути невдалим, оскільки (з причин, які не варто пояснювати) в деяких випадках немає підстав спонукати користувача.

(b) У дисертації Роя немає нічого, що дозволяє припустити, що це суперечить духу REST - чому б це було, оскільки HTTP - це лише одна реалізація REST, тому чому передача параметрів HTTP має значення


Чи може хтось вказати мені на остаточне твердження про те, що цвяхи є причиною, чому це не ВІДПОВІДНО?

Що стосується питання, якщо користувач не вказав force_delete, то я повертаюся 409 Conflict- це найбільш підходящий код відповіді?


Слідувати

Після деяких подальших досліджень я думаю, що додавання параметрів до DELETE може порушити декілька принципів.

Перший полягає в тому, що реалізація, можливо, порушує "Уніфікований інтерфейс" (див. Розділ 5.1.5 дисертації Роя

Додаючи "force_delete", ми додаємо додаткове обмеження на вже чітко визначений метод DELETE. Це обмеження має значення лише для нас.

Ви також можете стверджувати, що він порушує "5.1.2 клієнт-сервер", оскільки діалог підтвердження насправді викликає занепокоєння інтерфейсу, і знову не всі клієнти захочуть підтвердити видалення.

Пропозиції кому?


1
Ваш URL для дисертації Роя містить ")", який викликає 404. Працює ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm .
NuclearPeon

Відповіді:


78

Ні, це не ВІДПОВІДНО. Єдина причина, чому вам слід вводити verged ( force_delete) в URI, це якщо вам потрібно буде перевантажувати GET / POST методи в середовищі, де методи PUT / DELETE недоступні. Судячи з використання методу DELETE, це не так.

Код помилки HTTP 409/Conflictповинен використовуватися в ситуаціях, коли виникає конфлікт, який заважає службі RESTful виконувати операцію, але все ж є ймовірність, що користувач міг би вирішити конфлікт сам. Підтвердження попереднього видалення (де немає реальних конфліктів, які заважали б видаленню) не є конфліктом сам по собі, оскільки ніщо не заважає API виконувати запитувану операцію.

Як сказав Олексій (я не знаю, хто його порушив, він прав), це слід вирішувати в інтерфейсі, оскільки служба RESTful як така просто обробляє запити і тому повинна бути без громадянства (тобто вона не повинна покладатися на підтвердження, тримаючи будь-яку інформацію про запит на стороні сервера).

Два приклади, як це зробити в інтерфейсі, можна зробити:

  • pre-HTML5 : * покажіть користувачеві діалогове вікно підтвердження JS та надішліть запит, лише якщо користувач підтвердить це
  • HTML5 : * використовуйте форму з дією DELETE, де форма міститиме лише кнопки "Підтвердити" та "Скасувати" ("Підтвердити" була б кнопкою подання)

(*) Зауважте, що версії HTML до 5 не підтримують методи PUT і DELETE HTTP спочатку, проте більшість сучасних браузерів можуть виконувати ці два способи за допомогою AJAX-дзвінків. Детальну інформацію про підтримку крос-браузера див. У цій темі .


Оновлення (на основі додаткових розслідувань та обговорень):

Сценарій, коли служба вимагає наявності force_delete=trueпрапора, порушує єдиний інтерфейс , визначений у дисертації Роя Філдінга. Крім того, згідно з HTTP RFC , метод DELETE може бути замінений на початковому сервері (клієнті), маючи на увазі, що це не робиться на цільовому сервері (службі).

Отже, як тільки сервіс отримує DELETE-запит, він повинен обробити його, не потребуючи додаткового підтвердження (незалежно від того, чи служба насправді виконує операцію).


2
Чи можете ви пояснити, яке обмеження REST порушується? Зважаючи на те, що URI повинні бути непрозорими для клієнта, чому ви вважаєте, що очікування клієнта не відповідають вимогам використання HTTP DELETE, який видаляє один ресурс, але не може видалити інший. Я не впевнений, що 409 - найкращий код статусу, який потрібно повернути, але, окрім дещо дивної реалізації, я не можу знайти жодних обмежень REST, які порушуються.
Даррел Міллер

2
@Darrel: (imho) він порушує єдиний інтерфейс методом DELETE, не виконуючи відповідно до стандартів HTTP. Розглянемо клієнта REST, який передбачає стандартну послугу REST - як сервіс повідомить клієнту, що його потрібно додати force_delete=true? Відповідно до HTTP RFC, метод DELETE може бути замінений на початковому сервері (клієнті), маючи на увазі, що це не робиться на цільовому сервері (службі). Тому я розумію, що як тільки сервіс отримує DELETE-запит, він повинен обробляти його, не потребуючи підтвердження (незалежно від того, чи служба насправді виконує операцію).
MicE

1
@Chris, до вашого другого моменту: так, це теж моє розуміння, тобто, що держава передбачає справжній конфлікт, а не необхідність підтвердження. Я щойно помітив оновлення, яке ви зробили у своєму запитанні, і я згоден - поки я сам розглядав це, я прийшов до того ж висновку (що це порушує єдиний інтерфейс, і що підтвердження потрібно зробити на клієнті / інтерфейсі користувача сторона). Тут я також натрапив на дуже цікаву тему, це може допомогти: mail-archive.com/pylons-discuss@googlegroups.com/msg13578.html
MicE

2
@MicE Значною мірою я згоден з вами, що це не ідеальний спосіб впоратися з цим сценарієм. Я просто трохи прискіпливий до етикетки "це не RESTful". Деякий час тут ця фраза кидалася на все. Однак можна було б визначити правила для типу медіа, які говорять, якщо ви намагаєтесь ВИДАЛИТИ ресурс, і ви отримаєте помилку (я б сказав, що 403 заборонено було б краще 409), то клієнт повинен спробувати DELETE на пов'язаному ресурсі натиснувши на "force_delete = true". Певним чином це трохи схоже на авторизацію. Зробіть GET, отримайте 401, додайте заголовок auth та GET знову.
Даррел Міллер

2
@Darrel: це дуже вдалий момент, дякую. І я бачив, як люди самі кидають не RESTful етикетку. Можливо, в даний час бар'єр між сервісами та веб-додатками стає дуже туманним, тому один набір людей може бачити це з точки зору чистого обслуговування, а інші бачать це зі змішаної точки зору програми / послуги. Ось я вважаю, де реально постає питання про те, як зробити підтвердження. @Chris: оновлено - дякую сер за дуже цікаву тему та обговорення!
MicE

35

Я думаю, це неспокійно. Я не думаю, що спокійний сервіс не повинен відповідати вимозі змусити користувача підтвердити видалення. Я б вирішив це в інтерфейсі користувача.

Чи має значення вказати force_delete = true, якщо це API програми? Якщо хтось писав сценарій для видалення цього ресурсу, ви хочете змусити їх вказати force_delete = true, щоб фактично видалити ресурс?


Перший абзац вашої відповіді - це ваша думка, і я поважаю це, але ви не вказували на щось у літературі, що забороняє використовувати URI так: це все ще визначає ресурс і використовується найбільш відповідне дієслово HTTP. Відповідаючи на ваші запитання; так, це все одно мало б сенс (на мою думку). Я б очікував, що сценарій (можливо, заснований на CURL), щоб поважати відповідь 409 і запропонувати користувачеві, як запит може бути обурений - все на основі мого органу відповідей
Кріс МакКолі

Хороший момент щодо порівняння веб-API з API програми. Це часто є хорошим способом з’ясувати, чи API є RESTful чи ні.
Лоран

18

Це старе питання, але ось кілька коментарів ...

  1. У SQL команда DELETE приймає параметр "CASCADE", який дозволяє вказати, що залежні об'єкти також слід видалити. Це приклад параметра DELETE, який має сенс, але "man rm" може надати іншим. Як би ці випадки могли бути реалізовані в REST / HTTP без параметра?
  2. @Jan, мабуть, є усталеною умовою, що частина шляху URL-адреси ідентифікує ресурс, тоді як рядок запитів не (принаймні, не обов'язково). Прикладів багато: отримання одного і того ж ресурсу, але в іншому форматі, отримання конкретних полів ресурсу тощо. Якщо ми розглядаємо рядок запитів як частину ідентифікатора ресурсу, неможливо мати поняття "різні погляди одного ресурсу" не звертаючись до таких механізмів, які не є RESTful, такими як узгодження HTTP-вмісту (що може бути небажаним з багатьох причин).

Дякуємо, що додали це до розмови, навіть якщо це не багато розмови, оскільки триває роки.
silviot

6

Окрім відповіді Алекса:

Зауважте, що http: // server / resource / id? Force_delete = true ідентифікує інший ресурс, ніж http: // server / resource / id . Наприклад, велика різниця в тому, чи ви видалите / замовники /? Статус = старий чи / клієнти /.

Січ


Я не згоден, я міг надати декілька URI для ідентифікації одного і того ж ресурсу.
Кріс МакКолі

18
Так - всі можуть заплутатися :-)
Ян Альгерміссен

Вказівка ​​канонічних URI може допомогти у цьому: googlewebmastercentral.blogspot.com/2009/02/…
MicE

@Chris Має бути лише один URI, який повертає подання ресурсу. Інші URI можуть посилатися на ту саму концепцію, але при виконанні GET слід повернути 303 Див. Інше. А щоб протистояти очевидним запереченням проти цього, /foo.xml та /foo.json - це два різних ресурси.
Даррел Міллер

@Darrell - погоджуйтесь, але формат тут не проблема. Також .format - це конвенція щодо Rails та інших фреймворків, які не є частиною REST - для повноцінної реалізації цього вам слід використовувати узгодження контенту в HTTP з MIME або мікроформатами.
Кріс МакКолі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.