400 vs 422 response to POST of data

2019-01-02 21:50发布

I'm trying to figure out what the correct status code to return on different scenarios with a "REST-like" API that I'm working on. Let's say I have a end point that allows POST'ing purchases in JSON format. It looks like this:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

What should I return if the client sends me "sales_tax" (instead of the expected "tax"). Currently, I'm returning a 400. But, I've started questioning myself on this. Should I really be returning a 422? I mean, it's JSON (which is supported) and it's valid JSON, it's just doesn't contain all of the required fields.

9条回答
Deceive 欺骗
2楼-- · 2019-01-02 22:40

You should actually return "200 OK" and in the response body include a message about what happened with the posted data. Then it's up to your application to understand the message.

The thing is, HTTP status codes are exactly that - HTTP status codes. And those are meant to have meaning only at the transportation layer, not at the application layer. The application layer should really never even know that HTTP is being used. If you switched your transportation layer from HTTP to Homing Pigeons, it should not affect your application layer in any way.

Let me give you a non-virtual example. Let's say you fall in love with a girl and she loves you back but her family moves to a completely different country. She gives you her new snail-mail address. Naturally, you decide to send her a love letter. So you write your letter, put it into an envelope, write her address on the envelope, put a stamp on it and send it. Now let's consider these scenarios

  1. You forgot to write a street name. You will receive an unopened letter back with a message written on it saying that the address is malformed. You screwed up the request and the receiving post office is unable to handle it. That's the equivalent of receiving "400 Bad Request".
  2. So you fix the address and send the letter again. But due to some bad luck you totaly misspelled the name of the street. You will get the letter back again with a message saying, that the address doesn't exist. That's the equivalent of receiving "404 Not Found".
  3. You fix the address again and this time you manage to write the address correctly. Your girl receives the letter and writes you back. It's the equivalent of receiving "200 OK". However, this does not mean that you will like what she wrote in her letter. It simply means that she received your message and has a response for you. Until you open the envelope and read her letter you cannot know whether she misses you dearly or wants to break up with you.

In short: Returning "200 OK" doesn't mean that the server app has good news for you. It only means that it has some news.

PS: The 422 status code has a meaning only in the context of WebDAV. If you're not working with WebDAV, then 422 has exactly the same standard meaning as any other non-standard code = which is none.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-01-02 22:42

To reflect the status as of 2015:

Behaviorally both 400 and 422 response codes will be treated the same by clients and intermediaries, so it actually doesn't make a concrete difference which you use.

However I'd expect to see 400 currently used more widely, and furthermore the clarifications that the HTTPbis spec provides make it the more appropriate of the two status codes:

  • The HTTPbis spec clarifies the intent of 400 to not be solely for syntax errors. The broader phrase "indicates that the server cannot or will not process the request due to something which is perceived to be a client error" is now used.
  • 422 Is specifically a WebDAV extension, and is not referenced in RFC 2616 or in the newer HTTPbis specification.

For context, HTTPbis is a revision of the HTTP/1.1 spec that attempts to clarify areas that where unclear or inconsistent. Once it has reached approved status it will supersede RFC2616.

查看更多
Rolldiameter
4楼-- · 2019-01-02 22:45

There is no correct answer, since it depends on what the definition of "syntax" is for your request. The most important thing is that you:

  1. Use the response code(s) consistently
  2. Include as much additional information in the response body as you can to help the developer(s) using your API figure out what's going on.=

Before everyone jumps all over me for saying that there is no right or wrong answer here, let me explain a bit about how I came to the conclusion.

In this specific example, the OP's question is about a JSON request that contains a different key than expected. Now, the key name received is very similar, from a natural language standpoint, to the expected key, but it is, strictly, different, and hence not (usually) recognized by a machine as being equivalent.

As I said above, the deciding factor is what is meant by syntax. If the request was sent with a Content Type of application/json, then yes, the request is syntactically valid because it's valid JSON syntax, but not semantically valid, since it doesn't match what's expected. (assuming a strict definition of what makes the request in question semantically valid or not).

If, on the other hand, the request was sent with a more specific custom Content Type like application/vnd.mycorp.mydatatype+json that, perhaps, specifies exactly what fields are expected, then I would say that the request could easily be syntactically invalid, hence the 400 response.

In the case in question, since the key was wrong, not the value, there was a syntax error if there was a specification for what valid keys are. If there was no specification for valid keys, or the error was with a value, then it would be a semantic error.

查看更多
登录 后发表回答