I'm building an application with a REST-based API and have come to the point where i'm specifying status codes for each requests.
What status code should i send for requests failing validation or where a request is trying to add a duplicate in my database?
I've looked through http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html but none of them seems right.
Is there a common practice when sending status codes?
200,300, 400, 500 are all very generic. If you want generic, 400 is OK.
422 is used by an increasing number of APIs, and is even used by Rails out of the box.
No matter which status code you pick for your API, someone will disagree. But I prefer 422 because I think of '400 + text status' as too generic. Also, you aren't taking advantage of a JSON-ready parser; in contrast, a 422 with a JSON response is very explicit, and a great deal of error information can be conveyed.
Speaking of JSON response, I tend to standardize on the Rails error response for this case, which is:
This format is perfect for form validation, which I consider the most complex case to support in terms of 'error reporting richness'. If your error structure is this, it will likely handle all your error reporting needs.
Status Code 304 Not Modified would also make an acceptable response to a duplicate request. This is similar to processing a header of
If-None-Match
using an entity tag.In my opinion, @Piskvor's answer is the more obvious choice to what I perceive is the intent of the original question, but I have an alternative that is also relevant.
If you want to treat a duplicate request as a warning or notification rather than as an error, a response status code of
304
Not Modified andContent-Location
header identifying the existing resource would be just as valid. When the intent is merely to ensure that a resource exists, a duplicate request would not be an error but a confirmation. The request is not wrong, but is simply redundant, and the client can refer to the existing resource.In other words, the request is good, but since the resource already exists, the server does not need to perform any further processing.
A duplicate in the database should be a
409 CONFLICT
.I recommend using
422 UNPROCESSABLE ENTITY
for validation errors.I give a longer explanation of 4xx codes here: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/
For input validation failure: 400 Bad Request + your optional description. This is suggested in the book "RESTful Web Services". For double submit: 409 Conflict
Update June 2014
The relevant specification used to be RFC2616, which gave the use of 400 (Bad Request) rather narrowly as
So it might have been argued that it was inappropriate for semantic errors. But not any more; since June 2014 the relevant standard RFC 7231, which supersedes the previous RFC2616, gives the use of 400 (Bad Request) more broadly as
You should definitely give a more detailed explanation in the response headers and/or body (e.g. with a custom header -
X-Status-Reason: Validation failed
).Ember-Data's ActiveRecord adapter expects
422 UNPROCESSABLE ENTITY
to be returned from server. So, if you're client is written in Ember.js you should use 422. Only then DS.Errors will be populated with returned errors. You can of course change 422 to any other code in your adapter.