Reputation: 8933
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"}]
Upvotes: 399
Views: 1597011
Reputation: 55
I know I come here a little bit lately but hope this can help
Based on the RFC 2616 (1999)
10.4.1 400 Bad Request The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
and RFC 4918 (2017)
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.
So IMO, the 400
is suitable for [{blah:"Roman"}]
due to the server can not accept the field blah
for further logical handling.
And 422
is a better choice for [{requestedResource:"Roman"}]
because the server can accept the requestedResource
field but some business logic rules do not take the value Roman
as a valid entity,
Upvotes: 1
Reputation: 221
This reminds me of a common dialog with others, "I understand - I just don't Agree"
400 means the server didn't understand
200 means the server understood exactly and fully processed the request.
When a server returns 200 it is saying, "I understood what you are asking for, I processed it without unexpected errors, and here is my proper response"
200 means you can trust the answer sent in the response. Maybe the answer is "Romans aren't allowed" - but still, it is a proper answer, generated without any unexpected problems.
200 doesn't express any information about Expected errors or Handled Exceptions - because that is not part of the Message Transport process. These are status codes about HTTP, the Status of the Transport itself.
I believe Blurring the line between "Transport/Communication" VS "Processing" should be avoided.
For those who prefer HTTP Codes to indicate problem in processing (the "I don't agree" part) it seems 409 Conflict is the most applicable to "Romans not allowed"
RFC 7231 409 Conflict
Conflict pretty much means "lack of agreement" right?
No matter what you choose for HTTP response code, it seems everyone agrees your response should explain Why it failed, and what to do to resolve it. In the case of Roman, maybe return a list of acceptable values for the field?
Upvotes: 9
Reputation: 30310
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 400s.
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.
Upvotes: 406
Reputation: 11085
As a complementary, for those who might meet the same issue as mine, I'm using $.ajax
to post form data to server and I also got the 400
error at first.
Assume I have a javascript variable,
var formData = {
"name":"Gearon",
"hobby":"Be different"
};
Do not use variable formData
directly as the value of key data
like below:
$.ajax({
type: "post",
dataType: "json",
url: "http://localhost/user/add",
contentType: "application/json",
data: formData,
success: function(data, textStatus){
alert("Data: " + data + "\nStatus: " + status);
}
});
Instead, use JSON.stringify to encapsulate the formData
as below:
$.ajax({
type: "post",
dataType: "json",
url: "http://localhost/user/add",
contentType: "application/json",
data: JSON.stringify(formData),
success: function(data, textStatus){
alert("Data: " + data + "\nStatus: " + status);
}
});
Anyway, as others have illustrated, the error is because the server could not recognize the request cause malformed syntax, I'm just raising a instance at practice. Hope it would be helpful to someone.
Upvotes: 6
Reputation: 3229
First check the URL it might be wrong, if it is correct then check the request body which you are sending, the possible cause is request that you are sending is missing right syntax.
To elaborate , check for special characters in the request string. If it is (special char) being used this is the root cause of this error.
try copying the request and analyze each and every tags data.
Upvotes: 7
Reputation: 5304
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:
Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.
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:
{
"error_type" : "unsupported_resource",
"error_description" : "\"Roman\" is not supported"
}
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:
{
"error_type" : "malformed_json",
"error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}
Upvotes: 60
Reputation: 1102
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 is 415
:
The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
If the request payload is syntactically correct but semantically incorrect, the non-standard 422
response code may be used, or the standard 403
status code:
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated.
Upvotes: 19
Reputation:
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.
Upvotes: 24
Reputation: 1095
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 the requestedResource
value is incorrect than a 400 error would be appropriate.
Upvotes: 10
Reputation: 30446
From w3.org
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
Upvotes: 87