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

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


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

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

например.

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

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

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

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


Может ли кто-нибудь указать мне на окончательное утверждение, которое указывает на причину, почему это не RESTful?

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


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

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

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

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

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

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

Ответ 1

Нет, это не RESTful. Единственная причина, по которой вы должны положить глагол (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

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

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

Ответ 3

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

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

Ответ 4

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

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

Jan