Разрешено ли тело сущности для HTTP-запроса на удаление?

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

9 ответов


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

Microsoft видит это так же (я слышу ропот в аудитории), они заявляют в статье MSDN о метод удаления ADO.NET Data Services Framework:

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

дополнительно вот это адресу rfc2616 (HTTP 1.1) должен сказать в отношении запросов:

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

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

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

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

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


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


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

Вы читаете версию 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;
    }
}

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

раздел 4.3:

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

и раздел 9.7:

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

успешный ответ должен быть 200 (OK), если ответ включает сущность, описывающая состояние, 202 (принято), если действие не еще принят или 204 (без содержания), Если действие было принято но ответ не включает сущность.

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

таким образом, это явно не разрешено или запрещено, и есть вероятность, что прокси-сервер по пути может удалить тело сообщения (хотя он должен читайте и вперед).


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


кажется, ElasticSearch использует это: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api

Что означает, что Нетти поддерживает это.

Как упоминалось в комментариях, это может быть не так больше


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

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


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

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

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

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