Is an entity body allowed for an HTTP DELETE request?

HttpRest

Http Problem Overview


When issuing an HTTP DELETE request, the request URI should completely identify the resource to delete. However, is it allowable to add extra meta-data as part of the entity body of the request?

Http Solutions


Solution 1 - Http

The spec does not explicitly forbid or discourage it, so I would tend to say it is allowed.

Microsoft sees it the same way (I can hear murmuring in the audience), they state in the MSDN article about the DELETE Method of ADO.NET Data Services Framework:

> If a DELETE request includes an entity body, the body is ignored [...]

Additionally here is what RFC2616 (HTTP 1.1) has to say in regard to requests:

  • an entity-body is only present when a message-body is present (section 7.2)
  • the presence of a message-body is signaled by the inclusion of a Content-Length or Transfer-Encoding header (section 4.3)
  • a message-body must not be included when the specification of the request method does not allow sending an entity-body (section 4.3)
  • an entity-body is explicitly forbidden in TRACE requests only, all other request types are unrestricted (section 9, and 9.8 specifically)

For responses, this has been defined:

  • whether a message-body is included depends on both request method and response status (section 4.3)
  • a message-body is explicitly forbidden in responses to HEAD requests (section 9, and 9.4 specifically)
  • a message-body is explicitly forbidden in 1xx (informational), 204 (no content), and 304 (not modified) responses (section 4.3)
  • all other responses include a message-body, though it may be of zero length (section 4.3)

Solution 2 - Http

The latest update to the HTTP 1.1 specification (RFC 7231) explicitly permits an entity-body in a DELETE request: > A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.

Solution 3 - Http

Some versions of Tomcat and Jetty seem to ignore a entity body if it is present. Which can be a nuisance if you intended to receive it.

Solution 4 - Http

One reason to use the body in a delete request is for optimistic concurrency control.

You read version 1 of a record.

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

Your colleague reads version 1 of the record.

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

Your colleague changes the record and updates the database, which updates the version to 2:

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

You try to delete the record:

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

You should get an optimistic lock exception. Re-read the record, see that it's important, and maybe not delete it.

Another reason to use it is to delete multiple records at a time (for example, a grid with row-selection check-boxes).

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

Notice that each message has its own version. Maybe you can specify multiple versions using multiple headers, but by George, this is simpler and much more convenient.

This works in Tomcat (7.0.52) and Spring MVC (4.05), possibly w earlier versions too:

@RestController
public class TestController {

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

Solution 5 - Http

Just a heads up, if you supply a body in your DELETE request and are using a google cloud HTTPS load balancer, it will reject your request with a 400 error. I was banging my head against a wall and came to found out that Google, for whatever reason, thinks a DELETE request with a body is a malformed request.

Solution 6 - Http

It appears to me that https://www.rfc-editor.org/rfc/rfc2616">RFC 2616 does not specify this.

From section 4.3:

> The presence of a message-body in a request is signaled by the > inclusion of a Content-Length or Transfer-Encoding header field in > the request's message-headers. A message-body MUST NOT be included in > a request if the specification of the request method (section 5.1.1) > does not allow sending an entity-body in requests. A server SHOULD > read and forward a message-body on any request; if the request method > does not include defined semantics for an entity-body, then the > message-body SHOULD be ignored when handling the request.

And section 9.7:

> The DELETE method requests that the origin server delete the resource > identified by the Request-URI. This method MAY be overridden by human > intervention (or other means) on the origin server. The client cannot > be guaranteed that the operation has been carried out, even if the > status code returned from the origin server indicates that the action > has been completed successfully. However, the server SHOULD NOT > indicate success unless, at the time the response is given, it > intends to delete the resource or move it to an inaccessible > location. > > A successful response SHOULD be 200 (OK) if the response includes an > entity describing the status, 202 (Accepted) if the action has not > yet been enacted, or 204 (No Content) if the action has been enacted > but the response does not include an entity. > > If the request passes through a cache and the Request-URI identifies > one or more currently cached entities, those entries SHOULD be > treated as stale. Responses to this method are not cacheable.c

So it's not explicitly allowed or disallowed, and there's a chance that a proxy along the way might remove the message body (although it SHOULD read and forward it).

Solution 7 - Http

Roy Fielding on the HTTP mailing list clarifies that on the http mailing list https://lists.w3.org/Archives/Public/ietf-http-wg/2020JanMar/0123.html and says:

> GET/DELETE body are absolutely forbidden to have any impact whatsoever > on the processing or interpretation of the request

This means that the body must not modify the behavior of the server. Then he adds:

> aside from > the necessity to read and discard the bytes received in order to maintain > the message framing.

And finally the reason for not forbidding the body:

> The only reason we didn't forbid sending a body is > because that would lead to lazy implementations assuming no body would > be sent.

So while clients can send the payload body, servers should drop it and APIs should not define a semantic for the payload body on those requests.

Solution 8 - Http

Using DELETE with a Body is risky... I prefer this approach for List Operations over REST:

Regular Operations

GET /objects/ Gets all Objects

GET /object/ID Gets an Object with specified ID

POST /objects Adds a new Object

PUT /object/ID Adds an Object with specified ID, Updates an Object

DELETE /object/ID Deletes the object with specified ID

All Custom actions are POST

POST /objects/addList Adds a List or Array of Objects included in body

POST /objects/deleteList Deletes a List of Objects included in body

POST /objects/customQuery Creates a List based on custom query in body

If a client doesn't support your extended operations they can work in the regular way.

Solution 9 - Http

It is worth noting that the OpenAPI specification for version 3.0 dropped support for DELETE methods with a body:

see here and here for references

This may affect your implementation, documentation, or use of these APIs in the future.

Solution 10 - Http

I don't think a good answer to this has been posted, although there's been lots of great comments on existing answers. I'll lift the gist of those comments into a new answer:

This paragraph from RFC7231 has been quoted a few times, which does sum it up.

> A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.

What I missed from the other answers was the implication. Yes it is allowed to include a body on DELETE requests, but it's semantically meaningless. What this really means is that issuing a DELETE request with a request body is semantically equivalent to not including a request body.

Including a request body should not have any effect on the request, so there is never a point in including it.

tl;dr: Techically a DELETE request with a request body is allowed, but it's never useful to do so.

Solution 11 - Http

It seems ElasticSearch uses this: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/search-request-scroll.html#_clear_scroll_api

Which means Netty support this.

Like mentionned in comments it may not be the case anymore

Solution 12 - Http

In case anyone is running into this issue testing, No it is not universally supported.

I am currently testing with Sahi Pro and it is very apparent a http DELETE call strips any provided body data (a large list of id's to delete in bulk as per endpoint design).

I have been in contact with them several times as well as sent in three separate packages of scrips, images, logs for them to review and they still have not confirmed this. A failed patch, and a missed conference calls by their support later and I still haven't gotten a solid answer.

I am certain Sahi does not support this, and I would imagine many other tools follow suite.

Solution 13 - Http

This is not defined.

> A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.
> https://www.rfc-editor.org/rfc/rfc7231#page-29

Solution 14 - Http

Practical answer: NO

Some clients and servers ignore or even delete the body in DELETE request. In some rare cases they fail and return an error.

Solution 15 - Http

Might be the below GitHUb url will help you, to get the answer. Actually, Application Server like Tomcat, Weblogic denying the HTTP.DELETE call with request payload. So keeping these all things in mind, I have added example in github,please have a look into that

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHaackedView Question on Stackoverflow
Solution 1 - HttpTomalakView Answer on Stackoverflow
Solution 2 - HttpgrzesView Answer on Stackoverflow
Solution 3 - Httpevan.leonardView Answer on Stackoverflow
Solution 4 - HttpNeil McGuiganView Answer on Stackoverflow
Solution 5 - HttpBen FriedView Answer on Stackoverflow
Solution 6 - HttpAdam RosenfieldView Answer on Stackoverflow
Solution 7 - HttpRoberto PolliView Answer on Stackoverflow
Solution 8 - HttpEliezer GarzaView Answer on Stackoverflow
Solution 9 - HttpCleverPatrickView Answer on Stackoverflow
Solution 10 - HttpEvertView Answer on Stackoverflow
Solution 11 - HttpSebastien LorberView Answer on Stackoverflow
Solution 12 - HttpparkerView Answer on Stackoverflow
Solution 13 - HttpSimon JinView Answer on Stackoverflow
Solution 14 - HttpEnekoView Answer on Stackoverflow
Solution 15 - HttpAshishView Answer on Stackoverflow