400与422响应POST的数据

我试图找出什么是正确的状态代码返回不同的情况下,我正在工作的“rest般的”API。 比方说,我有一个结束点,允许在JSON格式POST'ing购买。 它看起来像这样:

{ "account_number": 45645511 "upc": "00490000486" "price": 1.00 "tax": 0.08 } 

如果客户向我发送“sales_tax”(而不是预期的“税”),我应该返回什么。 目前,我正在返回400.但是,我已经开始质疑自己了。 我真的应该回422吗? 我的意思是,这是JSON(这是支持),它是有效的JSON,它只是不包含所有必需的字段。

400错误的请求现在似乎是您的用例最好的HTTP / 1.1状态码。

在你提出问题的时候 (和我的原始答案), RFC 7231不是一件事; 在这一点上,我反对400 Bad Request因为RFC 2616说(重点是我的):

由于格式错误 ,服务器无法理解请求。

并且您描述的请求是语法上有效的JSON,这些JSON被包含在语法上有效的HTTP中,因此服务器对请求的语法没有任何问题。

然而 正如Lee Saferite在评论中所指出的那样 , RFC 7231废弃了RFC 2616,并没有包括这样的限制 :

400(错误请求)状态码指示服务器由于被认为是客户端错误(例如格式错误的请求语法,无效请求消息成帧或欺骗性请求路由)而不能或不会处理该请求。


然而, 在重写之前 (或者如果你想歪曲RFC 7231,现在只是一个build议的标准), 422 Unprocessable Entity不可422 Unprocessable Entity似乎并不是你的使用情况的不正确的 HTTP状态码,因为正如RFC 4918说:

虽然HTTP / 1.1提供的状态码足以描述WebDAV方法遇到的大多数错误情况,但是有一些错误不能完整地归入现有的类别。 本规范定义了为WebDAV方法开发的额外状态代码(第11节)

而对422的描述说:

422(不可处理的实体)状态码意味着服务器理解请求实体的内容types(因此415(不支持的媒体types)状态码是不合适的),并且请求实体的语法是正确的(因此400(错误的请求)状态码不合适),但无法处理包含的说明。

(注意语法的引用;我怀疑7231也部分废弃了4918)

这听起来你的情况完全一样,但为了万一有什么疑问,还是说:

例如,如果XML请求主体包含格式正确(即,语法正确),但语义错误的XML指令,则可能出现此错误情况。

(将“XML”replace为“JSON”,我认为我们可以同意这是你的情况)

现在,有人会反对RFC 4918是关于“Web分布式创作和版本控制(WebDAV)的HTTP扩展”,并且你(大概)没有涉及到WebDAV,所以不应该使用它。

考虑到在原始标准中使用错误代码(明确不包括情况)和使用描述情况的扩展名之间的select,我会select后者。

此外, RFC 4918第21.4节涉及IANA超文本传输​​协议(HTTP)状态码registry ,其中可以find422。

我build议HTTP客户端或服务器使用来自该registry的任何状态代码是完全合理的,只要它们正确地执行。


但是从HTTP / 1.1开始, RFC 7231就具有牵引力,所以只需使用400 Bad Request

反映截至2015年的状况:

在行为上,400和422响应码将被客户和中介处理,所以它实际上并没有产生具体的差异。

不过,我期望看到目前使用的更广泛的400,而且HTTPbis规范提供的澄清使得它更适合于两个状态代码:

  • HTTPbis规范阐明了400的意图不仅仅是语法错误。 现在使用更宽泛的短语“表示服务器不能或不会处理请求,因为被认为是客户端错误”。
  • 422特别是一个WebDAV扩展,并没有在RFC 2616或更新的HTTPbis规范中引用。

对于上下文,HTTPbis是对HTTP / 1.1规范的修订,试图澄清哪些地方不清楚或不一致。 一旦达到批准状态,它将取代RFC2616。

400错误请求是适合您的用例的正确的HTTP状态码。 代码由HTTP / 0.9-1.1 RFC定义。

由于格式错误,服务器无法理解请求。 客户端不应该不加修改地重复请求。

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

422不可处理实体由RFC 4918 – WebDav定义,只有在您支持WebDavfunction时才应使用此代码。 此代码不是HTTP / x RFC的一部分。 请注意,与400相比略有不同,请参见下面引用的文字。

如果XML请求主体包含格式正确的(即,语法正确),但语义错误的XML指令,则可能会出现此错误情况。

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

没有正确的答案,因为它取决于“语法”的定义是为您的请求。 最重要的是你:

  1. 一致地使用响应代码
  2. 在响应主体中尽可能多地包含其他信息,以帮助开发人员使用API​​来了解发生了什么。=

在所有人都跳到我面前说这里没有正确或错误的答案之前,让我来解释一下我是如何得出结论的。

在这个特定的例子中,OP的问题是关于一个JSON请求,它包含一个不同于预期的关键字。 现在,从自然语言angular度来看,收到的关键字名称与期望的关键字非常相似,但它严格地不同,因此不被(通常)被机器识别为等同的。

正如我上面所说,决定因素是语法的意思。 如果请求是使用内容typesapplication/json ,那么是的,请求在语法上是有效的,因为它是有效的JSON语法,但是在语义上是无效的,因为它与期望的不符。 (假定严格定义了有关请求的语义有效与否)。

另一方面,如果请求是使用更具体的自定义内容types(比如application/vnd.mycorp.mydatatype+json来发送的,那么可能会准确指定期望的字段,那么我会说请求可以很容易地在语法上无效,因此400的回应。

在这种情况下,由于密钥是错误的,而不是如果有什么有效密钥的规范则会出现 语法错误。 如果没有有效密钥的规范 ,或者错误是一个值 ,那么这将是一个语义错误。

您的情况:从RESTangular度来看, HTTP 400您的案例的正确状态代码,因为它的语法不正确,不过发送sales_tax而不是tax ,尽pipe它是一个有效的JSON。 将JSON映射到对象时,这通常由大多数服务器端框架强制执行。 但是,有一些REST实现会忽略JSON对象中的新key 。 在这种情况下,只接受有效字段的自定义content-type规范可以由服务器端强制执行。

422的理想情况:

在理想情况下,如果服务器理解请求实体的内容types并且请求实体的语法是正确的,但是由于其语义上的错误而无法处理数据,则422是优选的并且通常可以作为响应发送。

400以上的情况422:

请记住,响应码422是扩展的HTTP(WebDAV)状态码。 还有一些HTTP客户端/前端库不准备处理422,对于他们来说,就像“HTTP 422错误,因为它不是HTTP”一样简单。 从服务的angular度来看,400并不是很具体。

在企业架构中,服务主要部署在像SOA,IDM等服务层上。它们通常服务于从一个非常古老的本地客户端到最新的HTTP客户端的多个客户端。 如果其中一个客户端不处理HTTP 422,则选项是要求客户端将响应代码升级或更改为HTTP 400。 根据我的经验,这是非常罕见的,但仍有可能。 因此,在决定HTTP响应代码之前,总是需要仔细研究您的体系结构。

为了处理这样的情况,服务层通常使用versioning或设置configuration标志来为严格的HTTP一致性客户端发送400,而为其余的发送422。 这样,他们为现有的消费者提供向后兼容性支持,同时为新客户端提供使用HTTP 422的能力。


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 (eg, malformed request syntax, invalid request message framing, or deceptive request routing). 

这确认了服务器可以发送HTTP 400来请求无效的请求。 400并不仅仅指语法错误 ,但是,如果客户能够处理它,422仍然是一个真正的响应。

422无法处理的实体说明更新:2017年3月6日

什么是422不可处理的实体?

当一个请求格式正确时,会产生一个422状态码,但是由于语义错误,它不能被处理。 此HTTP状态在RFC 4918中引入,更具体地讲是面向Web分布式创作和版本控制(WebDAV)的HTTP扩展。

对于开发者是否应该向客户端返回一个400 vs 422的错误,有一些争议(更多关于这两个状态之间的差异)。 但是,在大多数情况下,只有在支持WebDAVfunction的情况下才能返回422状态。

RFC 4918第11.2节中对422状态码的逐字定义可以在下面看到。

422(不可处理的实体)状态码意味着服务器理解请求实体的内容types(因此415(不支持的媒体types)状态码是不合适的),并且请求实体的语法是正确的(因此400(错误的请求)状态码不合适),但无法处理包含的说明。

定义继续说:

例如,如果XML请求主体包含格式正确(即,语法正确),但语义错误的XML指令,则可能出现此错误情况。

400和422状态码

错误的请求错误使用400状态码,并且如果请求语法格式错误,包含无效的请求消息成帧或者具有欺骗性的请求路由select,则应该将其返回给客户端。 这个状态码可能看起来与422不可处理的实体状态非常相似,但是区分它们的一小块信息是这样一个事实,即422错误的请求实体的语法是正确的,而生成400的请求的语法是正确的错误是不正确的。

422状态的使用只能保留在非常特殊的用例中。 在其他大多数情况下,由于格式错误而发生客户端错误,应该使用400错误请求状态。

https://www.keycdn.com/support/422-unprocessable-entity/

首先这是一个很好的问题。

400错误请求 – 当请求中缺less关键信息时

例如授权标头或内容types标头。 服务器完全需要这个来理解请求。 这可能因服务器而异。

422不可处理的实体 – 当请求主体不能被分析时。

这比400更不严重。请求已经到达服务器。 服务器已经确认请求得到了基本结构权。 但是请求主体中的信息不能被parsing或理解。

例如Content-Type: application/xml当请求正文是JSON时。

这里有一篇文章列出了状态码及其在REST API中的使用。 https://metamug.com/article/status-codes-for-rest-api.php

你实际上应该返回“200 OK”,并在响应正文中包含关于发布数据发生了什么的消息。 然后,由您的应用程序来理解这个消息。

事情就是,HTTP状态码就是这个 – HTTP状态码。 而这些仅仅意味着在运输层而不是在应用层。 应用程序层应该甚至不知道正在使用HTTP。 如果您将传输层从HTTP切换到Homing鸽子,它不应以任何方式影响您的应用程序层。

让我给你一个非虚拟的例子。 比方说,你爱上一个女孩,她爱你,但她的家人搬到一个完全不同的国家。 她给你新的蜗牛邮件地址。 当然,你决定给她发一封情书。 所以你写信,把它放在一个信封里,在信封上写下她的地址,在上面盖上邮票并寄出。 现在我们来考虑这些情况

  1. 你忘了写街道名称。 您将收到一封未打开的信件,上面写着一条信息,说明地址格式不正确。 你搞砸了请求,接收邮局无法处理。 这相当于接收“400错误请求”。
  2. 所以你修复地址,然后再发信。 但是由于运气不好,你总是拼错了街道的名字。 你会再次收到一封信,说这个地址不存在。 这相当于接收“404未find”。
  3. 您再次修复地址,这次您设法正确地写入地址。 你的女孩收到这封信,写回你的信。 这相当于接收“200 OK”。 不过,这并不意味着你会喜欢她在信中写的东西。 这仅仅意味着她收到了你的信息,并为你作出回应。 在你打开信封阅读她的信之前,你不可能知道她是很想念你还是想和你分手。

总之:返回“200 OK”并不意味着服务器应用程序对您有好消息。 这只意味着它有一些消息。

PS:422状态码仅在WebDAV的上下文中有意义。 如果你没有使用WebDAV,那么422的标准含义与其他任何非标准代码完全相同。