POST 数据不正确时的 HTTP 状态(使用不存在的资源 ID)

HTTP status while POST with incorrect data (using id of resource which does not exist)

当我执行创建新用户的 POST 请求时, 到 return 的正确 HTTP 状态是什么,但它的参数之一不正确 - 我在用户数据中包含的公司 ID 在数据库中不存在。

POST 数据:{用户名:'newuser',年龄:99,company_id:34}

数据库中不存在id为34的公司

我在想是否可以:

在这里,这张图很好,用过很多次

Which code should I return?

我会选择 404。资源可能存在(不是格式错误)但它不存在(因此无法找到)。

对于 POST 请求,

404 Not Found 是 return 的问题状态。这意味着您要向其发送请求的资源不存在;来电者弄错了URL。

最明显(和通用)的答案是:400 Bad Request

这只是表明你的请求有问题(错误在于调用者而不是服务器),然后在你的响应正文中表达具体的错误细节。这通常是处理请求验证的方式。


理想 答案是通过向他们所属的公司发送请求来添加用户:

POST /company/34
Content-Type: application/json
{
    "username": "newuser",
    "age": 99
}

这意味着调用者必须找到一个有效的 company 资源来发送请求。如果 company/34 不存在,则 404 Not Found 响应是合适的;您尝试向不存在的公司添加用户。

这确实意味着您的 API 必须使用资源语义来构建,并且用户必须完全属于一家公司。

400422

首先,请记住这是一个 client error, so 5xx status codes are not suitable here. You should pick a 4xx 状态代码。

最明显的选项是 400 and 422:

  • 如果 JSON 语法无效, return 400.
  • 如果 JSON 语法有效 但其 内容无效, return 422表示服务器无法处理请求实体。

请参阅 RFC 4918 中的以下引用(对于您的情况,只需阅读 JSON 中的 XML):

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.

在此 中解决了类似的情况。


例如,GitHub API v3 也 returns 422 如果负载的内容包含无效值(但在语法上有效):

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. [...]

  2. Sending the wrong type of JSON values will result in a 400 Bad Request response. [...]

  3. Sending invalid fields will result in a 422 Unprocessable Entity response. [...]


Michael Kropat put together a set of diagrams 在选择最合适的状态代码时,这非常有见地。 4xx 状态码见下图: