400和422對數據POST的響應

本文翻譯自:400 vs 422 response to POST of data

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. 我正在嘗試使用正在使用的“類似REST”的API找出在不同情況下返回的正確狀態代碼是什麼。 Let's say I have a end point that allows POST'ing purchases in JSON format. 假設我有一個端點,允許JSON格式的POST購買。 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"). 如果客戶寄給我“ sales_tax”(而不是預期的“ tax”),我應該返回什麼。 Currently, I'm returning a 400. But, I've started questioning myself on this. 目前,我要退回400。但是,我開始對此提出質疑。 Should I really be returning a 422? 我真的應該歸還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. 我的意思是,它是JSON(受支持),並且是有效的JSON,只是不包含所有必填字段。


#1樓

參考:https://stackoom.com/question/15hAZ/和-對數據POST的響應


#2樓

400 Bad Request is proper HTTP status code for your use case. 400 Bad Request是您的用例的正確HTTP狀態代碼。 The code is defined by HTTP/0.9-1.1 RFC. 該代碼由HTTP / 0.9-1.1 RFC定義。

The request could not be understood by the server due to malformed syntax. 由於語法格式錯誤,服務器無法理解該請求。 The client SHOULD NOT repeat the request without modifications. 客戶不應在沒有修改的情況下重複請求。

http://tools.ietf.org/html/rfc2616#section-10.4.1 http://tools.ietf.org/html/rfc2616#section-10.4.1

422 Unprocessable Entity is defined by RFC 4918 - WebDav. 422無法處理的實體由RFC 4918-WebDav定義。 Note that there is slight difference in comparison to 400, see quoted text below. 請注意,與400相比略有差異,請參見下面的引文。

This error condition may occur if an XML request body contains well-formed (ie, syntactically correct), but semantically erroneous, XML instructions. 如果XML請求主體包含格式正確(即,語法正確)但語義上錯誤的XML指令,則可能發生此錯誤情況。

To keep uniform interface you should use 422 only in a case of XML responses and you should also support all status codes defined by Webdav extension, not just 422. 爲了保持統一的接口,您僅應在XML響應的情況下使用422,並且還應支持Webdav擴展定義的所有狀態代碼,而不僅僅是422。

http://tools.ietf.org/html/rfc4918#page-78 http://tools.ietf.org/html/rfc4918#page-78

See also Mark Nottingham's post on status codes: 另請參閱Mark Nottingham關於狀態碼的帖子:

it's a mistake to try to map each part of your application “deeply” into HTTP status codes; 嘗試將應用程序的每個部分“深入”映射到HTTP狀態代碼是一個錯誤; in most cases the level of granularity you want to be aiming for is much coarser. 在大多數情況下,您想要的粒度級別要粗糙得多。 When in doubt, it's OK to use the generic status codes 200 OK, 400 Bad Request and 500 Internal Service Error when there isn't a better fit . 如有疑問,可以使用通用狀態碼200 OK,400錯誤請求和500內部服務錯誤,如果不合適的話

How to Think About HTTP Status Codes 如何思考HTTP狀態碼


#3樓

400 Bad Request would now seem to be the best HTTP/1.1 status code for your use case. 對於您的用例,現在400 Bad Request似乎是最好的HTTP / 1.1狀態代碼。

At the time of your question (and my original answer), RFC 7231 was not a thing; 在提出問題時 (和我的原始答案), RFC 7231並不是問題。 at which point I objected to 400 Bad Request because RFC 2616 said (with emphasis mine): 當時我反對400 Bad Request因爲RFC 2616表示(重點是我的):

The request could not be understood by the server due to malformed syntax . 由於語法格式錯誤 ,服務器無法理解該請求。

and the request you describe is syntactically valid JSON encased in syntactically valid HTTP, and thus the server has no issues with the syntax of the request. 並且您描述的請求是語法有效的JSON(包含在語法有效的HTTP中),因此服務器的請求語法沒有問題。

However as pointed out by Lee Saferite in the comments , RFC 7231, which obsoletes RFC 2616, does not include that restriction : 但是, 正如Lee Saferite在評論中所指出的那樣 ,廢棄了RFC 2616的RFC 7231不包括該限制

The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (eg, malformed request syntax, invalid request message framing, or deceptive request routing). 400(錯誤請求)狀態代碼表示服務器由於某些原因(例如格式錯誤的請求語法,無效的請求消息框架或欺騙性的請求路由)而被視爲客戶端錯誤,因此服務器無法處理該請求。


However, prior to that re-wording (or if you want to quibble about RFC 7231 only being a proposed standard right now), 422 Unprocessable Entity does not seem an incorrect HTTP status code for your use case, because as the introduction to RFC 4918 says: 但是, 在重新措辭之前 (或者如果您想現在就僅將RFC 7231作爲提議的標準進行422 Unprocessable Entity ),對於您的用例, 422 Unprocessable Entity不可422 Unprocessable Entity似乎不是錯誤的 HTTP狀態代碼,因爲作爲RFC 4918的介紹說:

While the status codes provided by HTTP/1.1 are sufficient to describe most error conditions encountered by WebDAV methods, there are some errors that do not fall neatly into the existing categories. 雖然HTTP / 1.1提供的狀態代碼足以描述WebDAV方法遇到的大多數錯誤情況,但是有些錯誤並沒有很好地歸類到現有類別中。 This specification defines extra status codes developed for WebDAV methods (Section 11) 該規範定義了爲WebDAV方法開發的額外狀態代碼(第11節)

And the description of 422 says: 422的描述是

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. 422(不可處理實體)狀態代碼表示服務器瞭解請求實體的內容類型(因此415(不支持的媒體類型)狀態代碼不合適),並且請求實體的語法正確(因此400(錯誤請求) )狀態代碼不合適),但無法處理其中的說明。

(Note the reference to syntax; I suspect 7231 partly obsoletes 4918 too) (請注意對語法的引用;我懷疑7321也部分淘汰了4918)

This sounds exactly like your situation, but just in case there was any doubt, it goes on to say: 這聽起來完全像你的情況,但萬一有任何疑問,接着說:

For example, this error condition may occur if an XML request body contains well-formed (ie, syntactically correct), but semantically erroneous, XML instructions. 例如,如果XML請求主體包含格式正確(即,語法正確)但語義錯誤的XML指令,則可能發生此錯誤情況。

(Replace "XML" with "JSON" and I think we can agree that's your situation) (用“ JSON”替換“ XML”,我想我們可以同意這是您的情況)

Now, some will object that RFC 4918 is about "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" and that you (presumably) are doing nothing involving WebDAV so shouldn't use things from it. 現在,有些人會反對RFC 4918關於“ Web分佈式創作和版本控制(WebDAV)的HTTP擴展”,而您(大概)沒有做任何涉及WebDAV的事情,因此不應使用其中的內容。

Given the choice between using an error code in the original standard that explicitly doesn't cover the situation, and one from an extension that describes the situation exactly, I would choose the latter. 可以選擇在原始標準中使用錯誤代碼(不明確涵蓋該情況),而在擴展中準確描述該情況,則我選擇後者。

Furthermore, RFC 4918 Section 21.4 refers to the IANA Hypertext Transfer Protocol (HTTP) Status Code Registry , where 422 can be found. 此外, RFC 4918第21.4節引用了IANA超文本傳輸​​協議(HTTP)狀態代碼註冊表 ,可以在其中找到422。

I propose that it is totally reasonable for an HTTP client or server to use any status code from that registry, so long as they do so correctly. 我建議HTTP客戶端或服務器使用該註冊表中的任何狀態代碼是完全合理的,只要它們正確地使用了它們即可。


But as of HTTP/1.1, RFC 7231 has traction, so just use 400 Bad Request ! 但是從HTTP / 1.1開始, RFC 7231具有吸引力 ,因此只需使用400 Bad Request


#4樓

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.= 在響應正文中包含儘可能多的其他信息,以幫助使用API​​的開發人員瞭解正在發生的事情。=

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. 在此特定示例中,OP的問題是關於包含與預期不同的密鑰的JSON請求。 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. 如果該請求是使用Content application/json類型發送的,則是的,該請求在語法上是有效的,因爲它是有效的JSON語法,但在語義上無效,因爲它與預期的不匹配。 (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. 另一方面,如果以更特定的自定義內容類型(例如application/vnd.mycorp.mydatatype+json )發送了請求,也許可以確切指定期望的字段,那麼我可以說該請求可以很容易地在語法上無效,因此爲400。

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. 在這種情況下,由於密鑰是錯誤的,而不是value ,所以如果存在有效密鑰的規範則存在 語法錯誤。 If there was no specification for valid keys, or the error was with a value , then it would be a semantic error. 如果沒有有效密鑰的規範 ,或者錯誤帶有value ,那麼它將是語義錯誤。


#5樓

To reflect the status as of 2015: 爲反映截至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. 從行爲上講,客戶端和中介將對400和422響應代碼進行相同的處理,因此實際上並不會對您使用的內容產生任何具體的影響

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: 但是,我希望看到400當前被更廣泛地使用,此外, HTTPbis規範提供的說明使其更適合兩種狀態代碼:

  • The HTTPbis spec clarifies the intent of 400 to not be solely for syntax errors. HTTPbis規範闡明瞭400的意圖不僅僅是語法錯誤。 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 . 422特別是WebDAV擴展,在RFC 2616或較新的HTTPbis規範中未引用。

For context, HTTPbis is a revision of the HTTP/1.1 spec that attempts to clarify areas that where unclear or inconsistent. 就上下文而言,HTTPbis是HTTP / 1.1規範的修訂版,試圖澄清不清楚或不一致的區域。 Once it has reached approved status it will supersede RFC2616. 一旦達到批准狀態,它將取代RFC2616。


#6樓

Your case: HTTP 400 is the right status code for your case from REST perspective as its syntactically incorrect to send sales_tax instead of tax , though its a valid JSON. 您的案例:從REST的角度來看, HTTP 400是正確的狀態代碼,因爲它在語法上不正確,儘管發送了有效的JSON來發送sales_tax而不是tax This is normally enforced by most of the server side frameworks when mapping the JSON to objects. 在將JSON映射到對象時,大多數服務器端框架通常會強制執行此操作。 However, there are some REST implementations that ignore new key in JSON object. 但是,有些REST實現會忽略JSON對象中的新key In that case, a custom content-type specification to accept only valid fields can be enforced by server-side. 在這種情況下,服務器端可以強制執行僅接受有效字段的自定義content-type規範。

Ideal Scenario for 422: 422的理想方案:

In an ideal world, 422 is preferred and generally acceptable to send as response if the server understands the content type of the request entity and the syntax of the request entity is correct but was unable to process the data because its semantically erroneous. 在理想情況下,如果服務器理解請求實體的內容類型並且請求實體的語法正確但由於語義錯誤而無法處理數據,則422是首選並且通常可以作爲響應發送。

Situations of 400 over 422: 422中400的情況:

Remember, the response code 422 is an extended HTTP (WebDAV) status code. 請記住,響應代碼422是擴展的HTTP(WebDAV)狀態代碼。 There are still some HTTP clients / front-end libraries that aren't prepared to handle 422. For them, its as simple as "HTTP 422 is wrong, because it's not HTTP" . 還有一些HTTP客戶端/前端庫尚未準備好處理422。對於它們來說,它就像“ HTTP 422是錯誤的,因爲它不是HTTP”一樣簡單。 From the service perspective, 400 isn't quite specific. 從服務的角度來看,400不是很具體。

In enterprise architecture, the services are deployed mostly on service layers like SOA, IDM, etc. They typically serve multiple clients ranging from a very old native client to a latest HTTP clients. 在企業體系結構中,服務主要部署在SOA,IDM等服務層上。它們通常爲多個客戶端提供服務,從非常老的本機客戶端到最新的HTTP客戶端。 If one of the clients doesn't handle HTTP 422, the options are that asking the client to upgrade or change your response code to HTTP 400 for everyone. 如果其中一個客戶端不處理HTTP 422,則選項爲要求客戶端將所有人的響應代碼升級或更改爲HTTP 400。 In my experience, this is very rare these days but still a possibility. 以我的經驗,這幾天很少見,但仍有可能。 So, a careful study of your architecture is always required before deciding on the HTTP response codes. 因此,在決定HTTP響應代碼之前,始終需要仔細研究您的體系結構。

To handle situation like these, the service layers normally use versioning or setup configuration flag for strict HTTP conformance clients to send 400, and send 422 for the rest of them. 爲了處理這種情況,服務層通常對嚴格的HTTP一致性客戶端使用versioning或設置configuration標誌,以發送400,其餘的則發送422。 That way they provide backwards compatibility support for existing consumers but at the same time provide the ability for the new clients to consume HTTP 422. 這樣,它們爲現有使用者提供了向後兼容性支持,但同時也爲新客戶端提供了使用HTTP 422的能力。


The latest update to RFC7321 says: RFC7321的最新更新爲:

The 400 (Bad Request) status code indicates that the server cannot or
   will not process the request due to something that is perceived to be
   a client error (e.g., malformed request syntax, invalid request
   message framing, or deceptive request routing).

This confirms that servers can send HTTP 400 for invalid request. 這確認服務器可以發送HTTP 400進行無效請求。 400 doesn't refer only to syntax error anymore , however, 422 is still a genuine response provided the clients can handle it. 400不再僅指語法錯誤 ,但是422仍然是真正的響應,只要客戶可以處理它。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章