我正在尝试使用我正在处理的“类似 REST”的 API 找出在不同场景下返回的正确状态代码。假设我有一个端点,允许以 JSON 格式发布购买。它看起来像这样:
{ "account_number": 45645511, "upc": "00490000486", "price": 1.00, "tax": 0.08 }
如果客户向我发送“sales_tax”(而不是预期的“tax”),我应该返回什么。目前,我正在返回 400。但是,我已经开始质疑自己。我真的应该退回 422 吗?我的意思是,它是 JSON(受支持)并且它是有效的 JSON,它只是不包含所有必需的字段。
400 Bad Request 现在似乎是您的用例的最佳 HTTP/1.1 状态代码。
在您提出问题 (以及我最初的回答)时,RFC 7231还不是一回事。在这一点上我反对,400 Bad Request因为RFC 2616说(强调我的):
400 Bad Request
由于语法错误 ,服务器无法理解该请求。
并且您描述的请求是语法有效的 JSON 封装在语法有效的 HTTP 中,因此服务器对请求的 语法 没有问题。
然而 ,正如在评论中指出的那样,已淘汰 RFC 2616的 RFC 7231 不包括该限制:
400 (Bad Request) 状态码表示服务器不能或不会处理请求,因为某些东西被认为是客户端错误(例如,格式错误的请求语法、无效的请求消息帧或欺骗性请求路由)。
但是, 在重新措辞之前 (或者如果您想对 RFC 7231 现在只是一个 提议 的标准提出质疑),对于您的用例来说,这422 Unprocessable Entity似乎不是一个 不正确 的HTTP 状态代码,因为正如RFC 4918 的介绍所说:
422 Unprocessable Entity
虽然 HTTP/1.1 提供的状态码足以描述 WebDAV 方法遇到的大多数错误情况,但有些错误并没有完全归入现有类别。本规范定义了为 WebDAV 方法开发的额外状态代码(第 11 节)
并且描述422说:
422
422(Unprocessable Entity)状态码意味着服务器理解请求实体的内容类型(因此 415(Unsupported Media Type)状态码是不合适的),并且请求实体的语法是正确的(因此是 400(Bad Request) ) 状态码不合适)但无法处理包含的指令。
(注意对语法的引用;我怀疑 7231 也部分过时了 4918)
这听起来与您的情况 完全 一样,但以防万一有任何疑问,它会继续说:
例如,如果 XML 请求正文包含格式正确(即语法正确)但语义错误的 XML 指令,则可能会出现这种错误情况。
(将“XML”替换为“JSON”,我认为我们可以同意这是您的情况)
现在,有些人会反对 RFC 4918 是关于“Web 分布式创作和版本控制 (WebDAV) 的 HTTP 扩展”,并且您(大概)没有做任何涉及 WebDAV 的事情,所以不应该使用它。
考虑到在原始标准中使用明确不涵盖这种情况的错误代码和从准确描述情况的扩展中使用错误代码之间的选择,我会选择后者。
此外,RFC 4918 第 21.4 节引用了IANA 超文本传输协议 (HTTP) 状态代码注册表,其中 422 可以找到。
我建议 HTTP 客户端或服务器使用该注册表中的任何状态代码是完全合理的,只要它们正确使用即可。
但是从 HTTP/1.1 开始,RFC 7231 具有吸引力,所以只需使用400 Bad Request!