0

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?

DonkeyBanana
  • 3,266
  • 4
  • 26
  • 65

1 Answers1

2

Don't use the RFC 2616

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:

Status codes

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.

Unprocessable entity

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 a 415 (Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (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.

Decision charts

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:

HTTP status codes categories


Start here:

HTTP status codes


Choosing 2xx and 3xx status codes:

HTTP 2xx and 3xx status codes


Choosing 4xx status codes:

HTTP 4xx status codes


Choosing 5xx status codes:

HTTP 5xx status codes

Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • Thanks for the relevance remark and an awesome answer that educated me a lot. While I'm certain that **quality* of data* isn't a factor in the decision flow chart, I cant find it explicitly stated anywhere. Does it mean that it needs to be inferred from the lack of it or does it open a window to baking it into the response? It's been argued that *200 OK* might have the data quality implied to be feasible (if not certainly acceptable let alone correct). It's been argued also that it might have a different meaning when working with REST architecture. – DonkeyBanana Mar 22 '18 at 08:23
  • @DonkeyBanana HTTP status code aims to give to the client _the result of the attempt to understand and satisfy the request_. Your server certainly performs (or at least _should perform_) some kind of _validation_ on the data it receives from the client. If the request payload contains invalid data, then the entity cannot be processed hence the request cannot be accepted. So `200` won't fit here. – cassiomolin Mar 22 '18 at 10:16
  • I fear I was unclear. Let me try again. The request is valid (simply an URL and an ID). The server receives it and fetches some data from other sources, then returning it back to the client. Now, when the other system that provides some data to the server dicks around and does weird stuff, the data offered is poofy. Hence the data returned to the client from the server is poofy. – DonkeyBanana Mar 22 '18 at 22:51
  • The question is whether the message should say 200 OK (since the result of the attempt is correct (although the data is FUBAR but not due to issues in the client-server communication) or if it should say 500 Internal error (but still return the object with the poofy data). – DonkeyBanana Mar 22 '18 at 22:51
  • @DonkeyBanana So you are talking about the **response** payload instead of the request payload? Assuming it's a `GET` request to return a representation of a particular resource that was found on the server with the given identifier, return `200`. If the resource doesn't exist with the given identifier, , return `404`. If the request cannot be fulfilled due to a server error, return `500`. Pick the status code that best represents the result of the operation. – cassiomolin Mar 22 '18 at 23:41
  • Right. Got it. So, in conclusion - it doesn't make sense to receive in the response's payload an object corresponding by structure to what was expected **and** communicate 404 (or 500 for that matter). Correct? I reason as in the charts you provided (+1 for that) - if it's not found, it can't be returned. Instead we get 404 (= sorry dude, ain't gonna give ya nottin') or 500 (= oops dude, that hurts, ain't giving you nottin'). (I'm aware of the double negation - point being 404 and 500 must not present the object requested, right?) – DonkeyBanana Mar 23 '18 at 09:40