400与422的客户端错误请求区别

23
我已经阅读了很多关于客户端请求错误合适的HTTP状态码的帖子和文章。其他人建议使用400,因为它在RFC 7231中已被重新定义,尽管我不确定给出的示例是否涵盖了我脑海中的所有客户端错误,因为这些示例是语法上的。 400(错误请求)状态码表示服务器由于被认为是客户端错误的原因而无法或将不会处理请求(例如,格式错误的请求语法、无效的请求消息框架或欺骗性请求路由)。 我确实在rfc 7231的附录B中找到了这个声明: 400(错误请求)状态码已经放松,以便不仅限于语法错误。(第6.5.1节) 这是否意味着我可以将任何类型的客户端错误视为错误请求?使用400来处理客户端请求并在消息中指定更具体的错误是否更好?
422(无法处理的实体)状态码表示服务器理解请求实体的内容类型(因此不适用415(不支持的媒体类型)状态码),并且请求实体的语法正确(因此不适用400(错误的请求)状态码),但无法处理所包含的指令。例如,如果XML请求主体包含形式良好(即语法正确),但语义上错误的XML指令,则可能会出现此错误条件。
我可以使用这些WebDAV扩展代码来处理我的HTTP请求吗?在422的情况下,即使它不在核心HTTP代码中,我也可以使用它吗?
对于客户端错误,我应该使用400还是422?
以下是我考虑的可能的客户端错误:
1.) Invalid parameter. The client provided parameters but are found invalid. Example: I said that the userId is 1, but when I checked there's no userId of 1. Another example of invalid parameter is wrong data type.
2.) Missing required parameters
3.) Let's say I need to hash a value based on given params and it failed 
4.) Blocked content is being used. Like, i want to apply for membership and i passed the userId of 1. However, userId of one is blocked / deactivated
5.) When I try to delete an entry but the entry is still being used in another table. 
6.) Let's say i require a signature in my payload and the signature does not match when recalculated in the backend
7.) Let's say I have a value that counts a specific attribute like "shares" and it has reached the maximum value like 10.
etc...

更新:我检查了谷歌API错误,它们没有使用422。另一方面,Twitter使用422。我比以往任何时候都更困惑>。<虽然我认为400是更好的选择,因为它包含在RFC文档中,而422则不是。不过我可能错了。


1
你可以与客户端开发人员进行核对,或者你正在构建一个公共API吗?我会选择400,因为它对更多人有意义。如果你给他们一个422,一些(大多数)人将需要访问谷歌。这是你的API,你做决定。我猜。 - Jocke
谢谢@Jocke,你是对的。我选择了400。 - cessmestreet
1个回答

56
我可以使用这个WebDAV扩展代码来处理我的HTTP请求吗?在422的情况下,即使它不属于核心HTTP代码,我也可以使用它吗?
HTTP是一个可扩展的协议,422已经被注册到IANA,这使其成为标准状态码。因此,您可以在应用程序中使用422
自2022年6月起,422已在RFC 9110中定义,这是目前定义HTTP协议语义的文档:
“由于其普适性,状态码422(先前在RFC 4918的第11.2节中定义)已添加。”

作为参考,以下是422的定义:

15.5.21. 422 Unprocessable Content

422(无法处理的内容)状态码表示服务器理解请求内容的内容类型(因此不适用415(不支持的媒体类型)状态码),并且请求内容的语法正确,但无法处理所包含的指令。例如,如果XML请求内容包含格式良好(即语法上正确),但在语义上错误的XML指令,则可以发送此状态代码。

虽然在RFC 4918中定义,但422的原因短语是“Unprocessable Entity”。自从它被添加到RFC 9110以来,它的原因短语变为“Unprocessable Content”

我应该使用400还是422作为客户端错误?

你当然可以同时使用这两种状态码。一般来说,使用400表示负载中的语法错误或URL中的无效参数。而使用422表示负载中的语义问题。
例如,请看GitHub v3 API所采用的方法

Client errors

There are three possible types of client errors on API calls that receive request bodies:

  1. Sending invalid JSON will result in a 400 Bad Request response.

     HTTP/1.1 400 Bad Request
     Content-Length: 35
    
     {"message":"Problems parsing JSON"}
    
  2. Sending the wrong type of JSON values will result in a 400 Bad Request response.

     HTTP/1.1 400 Bad Request
     Content-Length: 40
    
     {"message":"Body should be a JSON object"}
    
  3. Sending invalid fields will result in a 422 Unprocessable Entity response.

     HTTP/1.1 422 Unprocessable Entity
     Content-Length: 149
    
     {
       "message": "Validation Failed",
       "errors": [
         {
           "resource": "Issue",
           "field": "title",
           "code": "missing_field"
         }
       ]
     }
    

选择最合适的4xx状态码

Michael Kropat整理了一组决策图表,帮助确定每种情况下最佳的状态码。请参见以下4xx状态码:

HTTP 4xx status codes

HTTP API的问题细节

有时候,HTTP状态码并不能提供足够的信息来帮助理解错误。RFC 7807定义了简单的JSON和XML文档格式,用于向客户端通报HTTP API中的问题。它是报告API错误的很好的起点。

它还定义了application/problem+jsonapplication/problem+xml媒体类型。


优秀的图表! - HappyTown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接