REST, HTTP DELETE и параметры - PullRequest
125 голосов
/ 29 марта 2010

Есть ли что-нибудь не-RESTful в предоставлении параметров для запроса HTTP DELETE?


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

Решение, которое мы приняли, заключается в передаче параметра в запрос на удаление, чтобы указать, что можно продолжить удаление («? Force_delete = true»)

, например

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

Я считаю, что это все еще успокаивает, так как:

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

(б) В диссертации Роя нет ничего, что могло бы предположить, что это противоречит духу REST - почему бы это сделать, поскольку HTTP является лишь одной реализацией REST, поэтому почему передача параметров HTTP имеет значение


Может ли кто-нибудь указать мне на однозначное утверждение, объясняющее причину, по которой это не RESTful?

По связанному вопросу, если пользователь не указывает force_delete, то я возвращаю 409 Conflict - это самый подходящий код ответа?


Последующие действия

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

Во-первых, реализация, возможно, нарушает «Единый интерфейс» (см. Раздел 5.1.5 Диссертация Роя

Добавляя force_delete, мы добавляем дополнительное ограничение к уже определенному методу DELETE. Это ограничение имеет значение только для нас.

Вы также можете утверждать, что это нарушает «Клиент-сервер 5.1.2», так как диалог подтверждения действительно является проблемой пользовательского интерфейса, и снова не все клиенты захотят подтвердить удаление.

Предложения кому-нибудь?

Ответы [ 4 ]

75 голосов
/ 30 марта 2010

Нет, это не RESTful. Единственная причина, по которой вам следует помещать глагол (force_delete) в URI, заключается в том, что вам нужно перегружать методы GET / POST в среде, где методы PUT / DELETE недоступны. Судя по вашему использованию метода DELETE, это не так.

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

Как сказал Алекс (я не знаю, кто за него проголосовал, он прав), это должно быть обработано в пользовательском интерфейсе, потому что служба RESTful сама по себе обрабатывает запросы и, следовательно, не должна иметь состояния (то есть не полагаться на Подтверждение путем удержания любой серверной информации о запросе).

Два примера того, как это сделать в пользовательском интерфейсе:

  • pre-HTML5 : * показывать пользователю диалог подтверждения JS и отправлять запрос только в том случае, если пользователь подтверждает его
  • HTML5 : * использовать форму с действием DELETE, где форма будет содержать только кнопки «Подтвердить» и «Отмена» («Подтвердить» будет кнопка отправки)

(*) Обратите внимание, что версии HTML до 5 изначально не поддерживают HTTP-методы PUT и DELETE, однако большинство современных браузеров могут выполнять эти два метода через вызовы AJAX. См. в этой теме для получения дополнительной информации о поддержке кросс-браузера.


Обновление (на основе дополнительных исследований и обсуждений):

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

Таким образом, как только служба получает запрос DELETE, она должна обработать его, не требуя дополнительного подтверждения (независимо от того, выполняет ли служба эту операцию).

34 голосов
/ 29 марта 2010

Я думаю, что это не для отдыха. Я не думаю, что служба restful должна обрабатывать требование принуждения пользователя подтвердить удаление. Я бы справился с этим в пользовательском интерфейсе.

Имеет ли смысл указание force_delete = true, если это был программный API? Если кто-то пишет сценарий для удаления этого ресурса, вы бы хотели, чтобы он указал force_delete = true, чтобы фактически удалить ресурс?

16 голосов
/ 02 марта 2011

Это старый вопрос, но вот некоторые комментарии ...

  1. В SQL команда DELETE принимает параметр «CASCADE», который позволяет указать, что зависимые объекты также должны быть удалены. Это пример параметра DELETE, который имеет смысл, но «man rm» может предоставить другие. Как эти случаи могут быть реализованы в REST / HTTP без параметра?
  2. @ Jan. Похоже, существует общепризнанное соглашение о том, что часть пути URL-адреса идентифицирует ресурс, а строка запроса - нет (по крайней мере, не обязательно). Примеров предостаточно: получение одного и того же ресурса, но в другом формате, получение определенных полей ресурса и т. Д. Если мы рассматриваем строку запроса как часть идентификатора ресурса, невозможно иметь понятие «разные представления одного и того же ресурса». без обращения к механизмам без RESTful, таким как согласование содержимого HTTP (что может быть нежелательным по многим причинам).
5 голосов
/ 30 марта 2010

В дополнение к ответу Алекса:

Обратите внимание, что http://server/resource/id?force_delete=true определяет ресурс, отличный от http://server/resource/id. Например, это огромная разница, если вы удаляете / Customers /? Status = old или /customers/.

Jan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...