Rails and REST: A reference to commonly-used HTTP status codes and their use in REST APIs

I see a fair amount of confusion with services over developers returning incorrect or incomplete HTTP failure codes from their RESTful controller actions, so here’s a quick reference to some of the most commonly-used codes in the 400 range and their specific use in a Rails context.

Code Rails symbol Use
401 :unauthorized The requester is not authorized to access this resource. Useful if you’re trying to roll some form of RESTful authentication (e.g. see Amazon’s S3 authentication).
404 :not_found The request is trying to access a resource that does not exist. Use this when your find method raises ActiveRecord::RecordNotFound, or your find_by returns nil.
405 :method_not_allowed The request is asking to perform a CRUD operation that your resource doesn’t support. It’s certainly much friendlier than bombing out because you haven’t defined a create method on your controller.
406 :not_acceptable The request is trying to access a resource in a format that your server doesn’t support. If a request doesn’t match any format you’ve provided in your respond_to block, Rails will automatically respond with this and an empty body (see ActionController::MimeResponds).
408 :request_timeout The timestamp on the request doesn’t match up to the server. Useful for authenticating requests that an attacker can’t play back at a later time.
409 :conflict The POST or PUT performed on your resource comes into conflict with an existing resource. Use this when your model fails a uniqueness_of validation. The easiest way to discover this is to compare the contents of the model error messages against ActiveRecord::Errors.default_error_messages[:taken].
422 :unprocessable_entity The request was correct but contains incorrect data, as with a regular model validation failure on a PUT or POST.

These are all the codes I’ve used in my RESTful services, but if you know of any others that I’ve missed post them in the comments or send me an email and I’ll incorporate them into the table above.

Also, it’s worth noting that REST, based as it is on the HTTP we know and love, is supposed to be reasonably human-friendly. In my opinion it’s not necessary to adhere strictly to the above conventions (although I try to) as long as the human beings trying to use your service understand why their requests failed and what they can do to fix them.

This is part of a series of posts on Rails and REST. Read the rest.

Rails and REST: Don't use auto-incremented database IDs as your resource identifier

Rails and REST: Nested XML and the Law of Demeter