I’ve had an enjoyable time getting down into a lot of gritty details about HTTP over the past year or so as I’ve worked on some webservices and a HTTP client tool for OS X. Every month, it seems like, I learn a little more about it based on the way my users use my app.
This past month, over the course of a few weeks, I got several tickets stating:
DELETEs are broken – they show as a POST on my server.
I was a little concerned when the first one came in – something as simple as sending the correct verb shouldn’t be broken, but if it were, that was pretty bad. A quick test showed that DELETEs were, in fact, working. After requesting a saved .httpreq file, I quickly pinpointed the problem – DELETEs normally worked, but when a request body was present, they were magically turned into POSTs.
Further investigation revealed the problem to be in the library I use to actually assemble and send the HTTP requests (this behavior is actually present in a number of HTTP libraries, it turns out).W hile fixing the problem (version 1.0.6 contains the fix and should be available on the app store soon), I wondered – Is it valid to include a body with a DELETE request?
I spent a bunch of time reading through the HTTP specification, and saw nothing that would indicate this situation was explicitly forbidden. In practice, however, a number of HTTP clients and servers seem to not approve – as I mentioned, a number of clients silently turn them into POSTs, and per this Stack Overflow thread, a number of servers silently discard the body of a DELETE request.
Regardless of whether it is allowed, or how it is implemented by popular clients and serveres, I think it is a bad idea in general. If you are consuming a service, you don’t really have a lot of choice in the matter, but if you are creating one, I think you shouldn’t create DELETE services that require bodies. This is due to how inconsistently it is implemented, and the fact that it doesn’t make a lot of sense to include a body with a delete in the first place – a body is supposed to represent the entity, but you are deleting it, so why do you need to send it?
There are a few reasons I think folks may try to develop services that rely on a body being sent with the DELETE request, and I think there are better ways to accomplish them:
1. To identify WHAT is to be deleted.
This should be specified by the URI itself.
2. To specify metadata about the delete request itself – for example, who deleted it or a comment related to the action.
In most cases, a header is much more appropriate for these metadata fields.