REST, HTTP DELETE and parameters
Asked Answered
L

4

148

Is there anything non-RESTful about providing parameters to a HTTP DELETE request?


My scenario is that I'm modelling the "Are you sure you want to delete that?" scenario. In some cases, the state of the resource suggests that the requested delete may be invalid. You can probably imagine some scenarios yourself where confirmation of a delete is required

The solution we have adopted is to pass a parameter to the delete request to indicate that it's ok to proceed with the delete ("?force_delete=true")

e.g.

DELETE http://server/resource/id?force_delete=true

I believe that it's still restful since:

(a) The semantics of DELETE are not being changed - the user can still send a normal DELETE request but this may fail with 409 and the body of the response will explain why. I say may fail because (for reasons not worth explaining) on some occasions there is no reason to prompt the user.

(b) There's nothing in Roy's dissertation to suggest that it's against the spirit of REST - why would there be since HTTP is only one implementation of REST so why would passing HTTP parameters matter


Can someone point me at a definitive statement that nails the reason why this isn't RESTful?

On a related question, if the user does not specify force_delete then I'm returning 409 Conflict - is that the most appropriate response code?


Follow up

After some further research, I think that adding parameters to the DELETE may violate several principles.

The first is that the implementation possibly violates the "Uniform Interface" (see section 5.1.5 of Roy's dissertation

By adding 'force_delete' we're adding an additional constraint onto the already well defined DELETE method. This constraint is meaningful only to us.

You could also argue that it violate the "5.1.2 Client-Server" since the confirmation dialogue is really a UI concern and again not all clients will want to confirm deletion.

Suggestions anyone?

Lenrow answered 29/3, 2010 at 16:1 Comment(2)
Your url for Roy's dissertation contains a ")" that causes a 404. ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm works.Strawser
This is a great question and I feel the force_delete option is a bit of a red herring. It's perfectly possible for a parameter to specify a record just as /foo GET ?r=123 makes sense, /foo DELETE ?r=123 makes sense.Determinism
L
84

No, it is not RESTful. The only reason why you should be putting a verb (force_delete) into the URI is if you would need to overload GET/POST methods in an environment where PUT/DELETE methods are not available. Judging from your use of the DELETE method, this is not the case.

HTTP error code 409/Conflict should be used for situations where there is a conflict which prevents the RESTful service to perform the operation, but there is still a chance that the user might be able to resolve the conflict himself. A pre-deletion confirmation (where there are no real conflicts which would prevent deletion) is not a conflict per se, as nothing prevents the API from performing the requested operation.

As Alex said, this should be handled in the UI, because a RESTful service as such just processes requests and should be therefore stateless (i.e. it must not rely on confirmations by holding any server-side information about of a request).

Two examples how to do this in UI would be to:

  • pre-HTML5:* show a JS confirmation dialog to the user, and send the request only if the user confirms it
  • HTML5:* use a form with action DELETE where the form would contain only "Confirm" and "Cancel" buttons ("Confirm" would be the submit button)

(*) Please note that HTML versions prior to 5 do not support PUT and DELETE HTTP methods natively, however most modern browsers can do these two methods via AJAX calls. See this thread for details about cross-browser support.


Update (based on additional investigation and discussions):

The scenario where the service would require the force_delete=true flag to be present violates the uniform interface as defined in Roy Fielding's dissertation. Also, as per HTTP RFC, the DELETE method may be overridden on the origin server (client), implying that this is not done on the target server (service).

So once the service receives a DELETE request, it should process it without needing any additional confirmation (regardless if the service actually performs the operation).

Longsuffering answered 29/3, 2010 at 20:59 Comment(8)
Could you explain which REST constraint is being violated? Considering that URIs should be opaque to the client, why do you believe that the client's expectations are not being met with the usage of an HTTP DELETE that deletes one resource but fails to delete another. I'm not sure 409 is the best status code to return but besides being a bit of a strange implementation, I cannot find any REST constraints that are being broken.Phratry
+1 for the well-argued opinion. I think you are arguing that in the absence of PUT/DELETE one should use POST to change the state of the resource but DELETE is available. I agree with that however DELETE is available and I haven'ts seen anything to suggest that using the URI like this is actually wrong - it still identifies the underlying resource.Lenrow
There is a conflict in my scenario - the resource state suggests that it is in use and should not be deleted.Lenrow
@Darrel: (imho) it violates the uniform interface by the DELETE method not performing as as per HTTP standards. Consider a REST client which assumes a standard REST service - how will the service let the client know that it needs to add force_delete=true? As per HTTP RFC, the DELETE method may be overriden on the origin server (client), implying that this is not done on the target server (service). So my understanding is that the once the service receives a DELETE request, it should process it without needing any confirmation (regardless if the service actually performs the operation).Longsuffering
@Chris, to your second point: yes, that is my understanding as well, i.e. that the state suggests a real conflict and not a need for confirmation. I just noticed the update which you did in your question, and I agree - while I was looking into it myself, I came to the same conclusion (that this violates the uniform interface, and that the confirmation should be done on the client/UI side). I also ran across a very interesting thread here, it might help: mail-archive.com/[email protected]/msg13578.htmlLongsuffering
@Longsuffering To a large extent I agree with you that it is not the ideal way to handle this scenario. I'm just being a bit picky about the "it's not RESTful" label. For a while here that phrase was thrown at everything. However, it would be possible to define rules for a media type that say if you attempt to DELETE a resource and you get an error (I would say 403 forbidden would be better than 409), then the client should attempt DELETE on a related resource by tacking on a "force_delete=true". In a way it is a bit like authorization. Do GET, get 401, add auth header and GET again.Phratry
@Darrel - I agree with the 'thrown at everything' that's why I was looking for pointers to the literature rather than opinions (however well argued). I think I've now convinced myself that it isn't RESTful because it violates at least one of Roy's constraints.Lenrow
@Darrel: that is a very good point, thank you. And I have seen people throw the not RESTful label myself. It might be the case that nowadays the barrier between services and web applications is becoming very foggy, so one set of people can see this from a pure-service point of view, while others see it from a mixed application/service point of view. That is I believe where the real question about how to do the confirmation comes into play. @Chris: updated - thank you sir for a very interesting topic and discussion!Longsuffering
L
38

I think this is non-restful. I do not think the restful service should handle the requirement of forcing the user to confirm a delete. I would handle this in the UI.

Does specifying force_delete=true make sense if this were a program's API? If someone was writing a script to delete this resource, would you want to force them to specify force_delete=true to actually delete the resource?

Lands answered 29/3, 2010 at 19:47 Comment(2)
The first paragraph of your response is your opinion and I respect that but you haven't pointed to something in the literature that forbids the use of the URI like this - it still identifies the resource and the most appropriate HTTP verb is being used. In answer to your questions; yes it would still make sense (in my opinion). I would expect a script (perhaps based on CURL) to respect the 409 response and suggest to the user how the request could be resent - all based on my response bodyLenrow
Good point about comparing the web API to a program's API. That's often a good way to find out if an API is RESTful or not.Brandwein
S
21

Here are some comments...

  1. In SQL, the DELETE command accepts a parameter "CASCADE", which allows you to specify that dependent objects should also be deleted. This is an example of a DELETE parameter that makes sense, but 'man rm' could provide others. How would these cases possibly be implemented in REST/HTTP without a parameter?
  2. @Jan, it seems to be a well-established convention that the path part of the URL identifies a resource, whereas the querystring does not (at least not necessarily). Examples abound: getting the same resource but in a different format, getting specific fields of a resource, etc. If we consider the querystring as part of the resource identifier, it is impossible to have a concept of "different views of the same resource" without turning to non-RESTful mechanisms such as HTTP content negotiation (which can be undesirable for many reasons).
Schoolmistress answered 2/3, 2011 at 12:0 Comment(1)
Thanks for adding this to the conversation, even if it's not much of a conversation since it lasts years.Suellensuelo
G
5

In addition to Alex's answer:

Note that http://server/resource/id?force_delete=true identifies a different resource than http://server/resource/id. For example, it is a huge difference whether you delete /customers/?status=old or /customers/.

Gratulate answered 29/3, 2010 at 21:2 Comment(6)
I disagree, I'm free to provide multiple URIs to identify the same resource.Lenrow
Yep - everyone is free to make a mess :-)Gratulate
Indication of canonical URIs could help with this: googlewebmastercentral.blogspot.com/2009/02/…Longsuffering
@Chris There should only be one URI that returns a representation of a resource. Other URI's can refer to the same concept but doing a GET should return a 303 See Other. And just to counter the obvious objection to this, /foo.xml and /foo.json are two different resources.Phratry
@Darrell - agree but the format isn't an issue here. Also the .format is a convention in Rails and other frameworks not a part of REST - you should be using the content negotiation in HTTP with MIME or microformats to fully implement this.Lenrow
A single resource can have multiple identifiers. edit: Idk. how this thread showed up more than a decade later. :SRovit

© 2022 - 2024 — McMap. All rights reserved.