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

Есть ли что-то не 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 ответа

Решение

Нет, это не 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, она должна обработать его, не требуя какого-либо дополнительного подтверждения (независимо от того, действительно ли служба выполняет операцию).

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

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

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

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

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

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

январь

Другие вопросы по тегам