POST 时数据不正确时的 HTTP 状态(使用不存在的资源 ID)
Posted
技术标签:
【中文标题】POST 时数据不正确时的 HTTP 状态(使用不存在的资源 ID)【英文标题】:HTTP status while POST with incorrect data (using id of resource which does not exist) 【发布时间】:2018-11-11 14:00:15 【问题描述】:当我执行 POST 请求以创建新用户时,要返回的正确 HTTP 状态是什么,但其中一个参数不正确 - 我在用户数据中包含的公司 ID数据库中不存在。
发布 数据:用户名:'newuser',年龄:99,company_id:34
数据库中不存在 id 为 34 的公司。
我在想是否可以:
400,一种无效数据,但有效但不存在id 404 - 但不清楚哪个资源不存在 409,因为这是一种冲突,用户可以通过更改公司 ID 来解决此问题 422? 或 500 - 因为这是一种数据库错误,而不允许存在不存在的 id【问题讨论】:
【参考方案1】:
400
或 422
首先,请记住它是client error,所以5xx
状态码不适合这里。然后你应该选择一个4xx
状态码。
最明显的选项是400
和422
:
400
。
如果 JSON 语法有效但其内容无效,则返回422
,表示服务器无法处理请求实体。
请参阅RFC 4918 中的以下引用(对于您的情况,当它说 XML 时,请阅读 JSON):
11.2. 422 Unprocessable Entity
422
(不可处理实体)状态码表示服务器 理解请求实体的内容类型(因此415
(不支持的媒体类型)状态码不合适),并且 请求实体的语法是正确的(因此是400
(Bad Request) 状态码不合适)但无法处理包含的 指示。例如,如果 XML 请求正文包含格式正确(即语法正确),但是 语义错误的 XML 指令。
answer 解决了类似的情况。
例如,如果负载的内容包含无效值(但在语法上有效),GitHub API v3 也会返回 422
:
在 API 调用中存在三种可能的客户端错误类型 接收请求正文:
发送无效的 JSON 将导致
400 Bad Request
响应。 [...]发送错误类型的 JSON 值将导致
400 Bad Request response
。 [...]发送无效字段将导致
422 Unprocessable Entity
响应。 [...]
Michael Kropat 将set of diagrams 放在一起,在选择最合适的状态代码时非常有见地。 4xx
状态码见下图:
【讨论】:
连接到WebDAV的这个状态怎么样?我在某处看到只有在支持 WebDAV 功能时才应该使用它。 @AgataAndrzejewska 某处在哪里? WebDAV 是一个 HTTP 扩展,422
是一个有效的 HTTP 状态码 registered in IANA。
我通常建议人们避免使用与 WebDAV 相关的状态代码,除非他们积极使用 WebDAV 标准作为其 API 的基础;我认为消费者会从一个晦涩的标准中挑选一个特定的(尽管是适当的)状态代码而忽略有关该标准的所有其他内容,这会让消费者感到困惑。 en.wikipedia.org/wiki/Principle_of_least_astonishment
CassioMazzochiMolin,我在这篇文章中读过:keycdn.com/support/422-unprocessable-entity
@PaulTurner 我在考虑简单性和清晰度以及 400 的描述“公司 ID 无效/不正确”。该请求似乎没有无效的语法问题。一般来说,我描述的 POST 请求似乎并不罕见,我没有看到 API 中返回很多 422 错误。【参考方案2】:
404 Not Found
是返回 POST
请求的有问题的状态。这意味着您发送请求的资源不存在;调用者的 URL 错误。
最明显(和通用)的答案是:400 Bad Request
这只是表明您的请求有问题(错误在于调用者而不是服务器),然后在您的响应正文中表达出问题的具体细节。这通常是处理请求验证的方式。
理想的答案是通过向他们所属的公司发送请求来添加用户:
POST /company/34
Content-Type: application/json
"username": "newuser",
"age": 99
这意味着调用者必须找到一个有效的company
资源才能将请求发送到。如果company/34
不存在,则404 Not Found
响应是合适的;您尝试将用户添加到不存在的公司。
这确实意味着您的 API 必须使用资源语义进行结构化,并且用户必须完全属于一家公司。
【讨论】:
我会选择422
,如我的answer 中所述。【参考方案3】:
这里,这张图很不错,我用过很多次了。
Which code should I return?
我会选择 404。资源可能存在(不是格式错误)但它不存在(因此无法找到)。
【讨论】:
谢谢,根据这张图我应该用422。404
在这里没有意义。
@CassioMazzochiMolin 您是否介意尝试添加一些有用的东西而不是无意义地抨击,比如为什么我的推理是错误的?以上是关于POST 时数据不正确时的 HTTP 状态(使用不存在的资源 ID)的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中使用 Wininet 发送 POST 请求时的编码问题