Разрешен ли объект сущности для запроса HTTP DELETE?

При выдаче запроса HTTP DELETE URI-запрос должен полностью идентифицировать ресурс для удаления. Однако можно ли добавить дополнительные метаданные как часть тела объекта запроса?

Ответ 1

Спецификация не запрещает или запрещает это явно, поэтому я бы сказал, что это разрешено.

Microsoft видит это так же (я слышу ропот в аудитории), в статье MSDN говорится о методе DELETE для служб данных ADO.NET Framework:

Если запрос DELETE включает в себя тело объекта, тело игнорируется [...]

Кроме того, здесь RFC2616 (HTTP 1.1) должен сказать в отношении запросов:

  • объект-тело присутствует только в том случае, когда присутствует тело сообщения (раздел 7.2).
  • наличие тела сообщения сигнализируется включением заголовка Content-Length или Transfer-Encoding (раздел 4.3)
  • тело сообщения не должно включаться, когда спецификация метода запроса не позволяет отправлять тело сущности (раздел 4.3).
  • объект-тело явно запрещен только в запросах TRACE, все остальные типы запросов неограниченны (разделы 9 и 9.8 конкретно)

Для ответов это было определено:

  • включено ли тело сообщения в зависимости от метода запроса и состояния ответа (раздел 4.3)
  • тело сообщения явно запрещено в ответах на запросы HEAD (особенно в разделах 9 и 9.4).
  • тело сообщения явно запрещено в 1xx (информационном), 204 (без содержимого) и 304 (не измененных) ответах (раздел 4.3).
  • все другие ответы включают тело сообщения, хотя оно может быть нулевой длины (раздел 4.3)

Ответ 2

Последнее обновление спецификации HTTP 1.1 (RFC 7231) явно разрешает сущности в запросе DELETE:

Полезная нагрузка в сообщении запроса DELETE не имеет определенной семантики; отправка тела полезной нагрузки по запросу DELETE может привести к тому, что некоторые существующие реализации отклонят запрос.

Ответ 3

Некоторые версии Tomcat и Jetty, похоже, игнорируют тело объекта, если оно присутствует. Что может быть неприятностью, если вы намеревались его получить.

Ответ 4

Одна из причин использования тела в запросе удаления для оптимистического управления concurrency.

Вы читаете версию 1 записи.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

Ваш коллега читает версию 1 записи.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

Ваш коллега меняет запись и обновляет базу данных, которая обновляет версию до 2:

PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }

Вы пытаетесь удалить запись:

DELETE /some-resource/1 { id:1, version:1 }
409 Conflict

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

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

DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content

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

Это работает в Tomcat (7.0.52) и Spring MVC (4.05), возможно, в более ранних версиях:

@RestController
public class TestController {

    @RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
    SomeBean echoDelete(@RequestBody SomeBean someBean) {
        return someBean;
    }
}

Ответ 5

Мне кажется, что RFC 2616 не указывает это.

Из раздела 4.3:

Наличие тела сообщения в запросе сигнализируется включение поля заголовка Content-Length или Transfer-Encoding в заголовки сообщений запроса. Тело сообщения НЕ ДОЛЖНО быть включено в запрос, если спецификация метода запроса (раздел 5.1.1) не позволяет отправлять тело объекта в запросы. Сервер ДОЛЖЕН читать и пересылать тело сообщения по любому запросу; если метод запроса не включает определенную семантику для объекта-тела, тогда тело сообщения ДОЛЖНО быть проигнорировано при обработке запроса.

И раздел 9.7:

Метод DELETE запрашивает, чтобы исходный сервер удалял ресурс идентифицированных Request-URI. Этот метод МОЖЕТ быть переопределен вмешательства (или других средств) на исходном сервере. Клиент не может чтобы операция была выполнена, даже если код состояния, возвращенный с исходного сервера, указывает, что действие успешно завершена. Однако сервер НЕ ДОЛЖЕН указать успех, если в момент ответа не будет намеревается удалить ресурс или перенести его на недоступный местоположение и др.

Успешный ответ ДОЛЖЕН быть 200 (ОК), если ответ включает объект, описывающий статус, 202 (принятый), если действие не выполнено все же было принято или 204 (без содержания), если действие было принято но ответ не включает сущность.

Если запрос проходит через кеш, а Request-URI идентифицирует один или несколько в настоящее время кэшированных объектов, эти записи ДОЛЖНЫ считаются устаревшими. Ответы на этот метод не являются cacheable.c

Таким образом, он явно не разрешен или запрещен, и есть вероятность, что прокси-сервер по пути может удалить тело сообщения (хотя он ДОЛЖЕН читать и пересылать его).

Ответ 6

Просто голова, если вы подаете тело в свой запрос DELETE и используете балансировщик нагрузки HTTPS для Google, он отклонит ваш запрос с ошибкой 400. Я ударился головой о стену и пришел к выводу, что Google по какой-то причине считает, что запрос DELETE с телом является искаженным запросом.

Ответ 8

Это не определено.

Полезная нагрузка в сообщении запроса DELETE не имеет определенной семантики; отправка тела полезной нагрузки по запросу DELETE может привести к тому, что некоторые существующие реализации отклонят запрос.
https://tools.ietf.org/html/rfc7231#page-29

Ответ 9

Стоит отметить, что в спецификации OpenAPI для версии 3.0 отсутствует поддержка методов DELETE с телом:

смотрите здесь и здесь для ссылок

Это может повлиять на вашу реализацию, документацию или использование этих API в будущем.

Ответ 10

В случае, если кто-то работает с этим тестированием проблем, Нет, он не поддерживается повсеместно.

В настоящее время я тестирую Sahi Pro, и очень очевидно, что http DELETE вызывает полоски любых предоставленных данных тела (большой список идентификаторов для удаления навалом в соответствии с дизайном конечной точки).

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

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

Ответ 11

Я не думаю, что хороший ответ на этот вопрос был опубликован, хотя было много хороших комментариев к существующим ответам. Я подниму суть этих комментариев в новый ответ:

Этот абзац из RFC7231 цитировался несколько раз, что подводит итог.

Полезная нагрузка в сообщении запроса DELETE не имеет определенной семантики; отправка тела полезной нагрузки по запросу DELETE может привести к тому, что некоторые существующие реализации отклонят запрос.

То, что я пропустил из других ответов, было значение. Да, разрешено включать тело в запросах DELETE, но это семантически бессмысленно. На самом деле это означает, что выдача запроса DELETE с телом запроса семантически эквивалентна отсутствию тела запроса.

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

tl; dr: Технически запрос DELETE с телом запроса разрешен, но это бесполезно.

Ответ 12

Использование DELETE с Body является рискованным... Я предпочитаю такой подход для операций со списками, а не для REST:

Регулярные операции

GET/objects/Получает все объекты

GET/object/ID Получает объект с указанным идентификатором

POST/objects Добавляет новый объект

PUT/object/ID Добавляет объект с указанным идентификатором, обновляет объект

DELETE/object/ID Удаляет объект с указанным идентификатором

Все пользовательские действия POST

POST/objects/addList Добавляет список или массив объектов, включенных в тело

POST/objects/deleteList Удаляет список объектов, включенных в тело

POST/objects/customQuery Создает список на основе пользовательского запроса в теле.

Если клиент не поддерживает ваши расширенные операции, он может работать в обычном режиме.

Ответ 13

Мне удалось реализовать операцию УДАЛИТЬ с телом запроса. Я использовал AWS Lambda и AWS API gateway и использовал язык Go.

Ответ 14

В Spring MVC при удалении ресурса с использованием REST мы возвращаем статус:

@ResponseStatus(HttpStatus.NO_CONTENT)

Ответ 15

Может быть, приведенный ниже URL-адрес GitHUb поможет вам получить ответ. На самом деле, сервер приложений, такой как Tomcat, Weblogic отклоняет вызов HTTP.DELETE с полезной нагрузкой запроса. Имея в виду все это, я добавил пример в github, пожалуйста, посмотрите на это

https://github.com/ashish720/spring-examples

Ответ 16

когда вы пытаетесь использовать type-is, чтобы определить, является ли запрос "запросом JSON" или нет, если delete request не включает объект bod, он будет возвращать false.