We had a discussion today about an transfer operation resulting in status code 200, OK. There were two objects returned looking like this.
First one being fairly graspable (and following the expected contract).
{ name: "john", age: 34, city: "stockholm" }
Second one, following the contract but with unquestionably wrong data.
{ name: null, age: -3.141526, city: "http://some.com/address/poof" }
One party claimed that the status code 200 is incorrect because the values are wrong. The other side argued that the status code describes the operation as such and the format of the request/response, which went well because the transfer agrees with the contract.
It's fairly obvious that the REST endpoint gets an exception from the sources it fetches the data from. And so, the first party wanted the result to be either 404 not found or 500 internal error. The other side was open to it under the condition that the object structure is empty (nulls all the way) in the former case and that it doesn't attempt to follow the agreed format in the latter case.
Checking out the Kamasutra it's said that:
The request has succeeded. The information returned with the response is dependent on the method used in the request.
Now, technically speaking, we can't know for sure if the resource requested has a name, might be planned to be born in PI years and happens to reside in a city that changed its name to an URL. That is actually possible, although highly unlikely. However, I'd like to see an explicit statement of what isn't included in status code 200.
The question: is it valid to demand status code 400 or higher because the values are seemingly (or even obviously) wrong?
The RFC 2616 is completely irrelevant nowadays once it has been replaced by a set of new RFCs that together define the HTTP/1.1 protocol:
For the HTTP status codes, refer to the RFC 7231. Such document defines what each status code indicates. Pick the one that best gives the result of the attempt to understand and satisfy the request.
This document also defines the classes of the status codes, that helps to determine the most suitable status for the response:
The first digit of the status-code defines the class of response. The last two digits do not have any categorization role. There are five values for the first digit:
1xx
(Informational): The request was received, continuing process
2xx
(Successful): The request was successfully received, understood, and accepted
3xx
(Redirection): Further action needs to be taken in order to complete the request
4xx
(Client Error): The request contains bad syntax or cannot be fulfilled
5xx
(Server Error): The server failed to fulfill an apparently valid request
Just bear in mind that HTTP status codes are extensible. The RFC 7231 does not include extension status codes defined in other specifications. The complete list of status codes is maintained by IANA.
The 2xx
class of status code indicates that request was successfully received, understood, and accepted. Once you won't accept invalid data, that is, an entity that cannot be processed by the server, the 200
status code is not suitable for the this situation.
The 422
status code is what you are looking for: the syntax of the request payload is valid but it cannot be processed due to invalid data. Have a look:
11.2. 422 Unprocessable Entity
The
422
(Unprocessable Entity) status code means the server understands the content type of the request entity (hence a415
(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a400
(Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.
For your situation, just read JSON instead of XML.
The 422
is registered in IANA and defined in the RFC 4918, the document that defines WebDAV, an extension for the HTTP protocol.
Michael Kropat put together a set of decision charts that helps determine the best status code for each situation. The status codes are grouped into three rough categories:
Start here:
Choosing 2xx
and 3xx
status codes:
Choosing 4xx
status codes:
Choosing 5xx
status codes: