I have a JSON request which I'm posting to a HTTP URL.
Should this be treated as 400
where requestedResource
field exists but "Roman"
is an invalid value for this field?
[{requestedResource:"Roman"}]
Should this be treated as 400
where "blah"
field doesn't exist at all?
[{blah:"Roman"}]
A 400 means that the request was malformed. In other words, the data stream sent by the client to the server didn't follow the rules.
In the case of a REST API with a JSON payload, 400's are typically, and correctly I would say, used to indicate that the JSON is invalid in some way according to the API specification for the service.
By that logic, both the scenarios you provided should be 400's.
Imagine instead this were XML rather than JSON. In both cases, the XML would never pass schema validation--either because of an undefined element or an improper element value. That would be a bad request. Same deal here.
Using
400
status codes for any other purpose than indicating that the request is malformed is just plain wrong.If the request payload contains a byte-sequence that could not be parsed as
application/json
(if the server expects that dataformat), the appropriate status code is415
:If the request payload is syntactically correct but semantically incorrect, the non-standard
422
response code may be used, or the standard403
status code:From w3.org
Think about expectations.
As a client app, you expect to know if something goes wrong on the server side. If the server needs to throw an error when
blah
is missing or therequestedResource
value is incorrect than a 400 error would be appropriate.Selecting a HTTP response code is quite an easy task and can be described by simple rules. The only tricky part which is often forgotten is paragraph 6.5 from RFC 7231:
Rules are as following:
So in your case I'd returned 400 error and something like this if "Roman" is obtained from user input and client must have specific reaction:
or a more generic error, if such situation is a bad logic error in a client and is not expected, unless developer made something wrong:
In neither case is the "syntax malformed". It's the semantics that are wrong. Hence, IMHO a 400 is inappropriate. Instead, it would be appropriate to return a 200 along with some kind of error object such as
{ "error": { "message": "Unknown request keyword" } }
or whatever.Consider the client processing path(s). An error in syntax (e.g. invalid JSON) is an error in the logic of the program, in other words a bug of some sort, and should be handled accordingly, in a way similar to a 403, say; in other words, something bad has gone wrong.
An error in a parameter value, on the other hand, is an error of semantics, perhaps due to say poorly validated user input. It is not an HTTP error (although I suppose it could be a 422). The processing path would be different.
For instance, in jQuery, I would prefer not to have to write a single error handler that deals with both things like 500 and some app-specific semantic error. Other frameworks, Ember for one, also treat HTTP errors like 400s and 500s identically as big fat failures, requiring the programmer to detect what's going on and branch depending on whether it's a "real" error or not.