Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should deleting a non-existent resource result in a 404 in RESTful Rails?

Tags:

In a brand new Rails application with a scaffolded RESTful model, the generated delete code looks like this:

class BeersController < ApplicationController   # DELETE /beers/1   # DELETE /beers/1.xml   def destroy     @beer = Beer.find(params[:id])     @beer.destroy      respond_to do |format|       format.html { redirect_to(beers_url) }       format.xml  { head :ok }     end   end end 

If a user tries to delete the same Beer twice (maybe a quick double-click, or actions in two different browser tabs) they will get a RecordNotFound error resulting in a 404 page. This is a pretty unfriendly experience; it seems like it would be better to complete the redirect back to beers_url regardless, possibly with a flash error, since there isn't really anything the user can do about the second delete failing.

An alternative approach is to act like the delete succeeded anyway with something like this:

def destroy   @beer = Beer.find_by_id(params[:id])   destroyed = @beer.try(:destroy)            respond_to do |format|     format.html { redirect_to(beers_url) }     format.xml  { destroyed ? head(:ok) : head(:not_found) }   end end 

I can understand the desire for a hard 404 error in the API use-case, but it's harder for me to justify for a web application. Can anyone provide a good reason why we should throw a scary error at the user in the name of RESTfulness?

(This question isn't particular to Rails, but I don't know how other frameworks handle this case out of the box).

like image 844
Brad Avatar asked Jun 24 '11 22:06

Brad


People also ask

Should a delete return a 404?

Rationale: DELETE should be idempotent. If you return 404 on a second DELETE, your response is changing from a success code to an error code. The client program may take incorrect actions based on the assumption the DELETE failed.

Should delete return 200 or 204?

A 204 ( No Content ) status code if the action has been enacted and no further information is to be supplied. A 200 ( OK ) status code if the action has been enacted and the response message includes a representation describing the status.

What should I return on Delete REST API?

DELETE API Response Codes. A successful response of DELETE requests SHOULD be an HTTP response code 200 (OK) if the response includes an entity describing the status. The status should be 202 (Accepted) if the action has been queued.

What status code should delete return?

For a DELETE request: HTTP 200 or HTTP 204 should imply "resource deleted successfully". HTTP 202 can also be returned by either operation and would imply that the instruction was accepted by the server, but not fully applied yet.


2 Answers

UPDATE: It turns out I was wrong: https://stackoverflow.com/a/24713946/14731


Previous answer: HTTP DELETE is an idempotent operation. Invoking it multiple times consecutively must result in the same behavior as the first. Meaning: you shouldn't return HTTP 404.

like image 116
Gili Avatar answered Nov 03 '22 21:11

Gili


I don't think you should ever throw the error at the user for the sake of holding up some standard - especially if this is a consumer facing app (as opposed to B2B). But you also shouldn't make your api change its status code just for this one situation. The resource doesn't exist anymore; so a 404 is a proper response.

I think there is a path of least (or lessor - is that even a word???) resistance here. I haven't explored ruby yet so I can't provide any usable implementation; but I'm somewhat experienced with web apps using html/css/js.

If there is some legitimate problem with users clicking a button twice; why not set up the button so that it disables when the request is submitted, and re-enables once the conditions are proper (request has come back)? In other words, avoid the if(this very specific situation) logic by making it impossible to get into the situation you're seeing. I'm assuming ruby has something specifically for handling requests and adding function handlers for different status codes; or at least non-200 status codes.

like image 35
Dave Avatar answered Nov 03 '22 22:11

Dave