Rest 400对422对数据发布的响应

Rest 400对422对数据发布的响应,rest,http-status-codes,Rest,Http Status Codes,我正试图找出在我正在使用的REST类API的不同场景中返回的正确状态代码。假设我有一个端点,允许以JSON格式发布购买。看起来是这样的: { "account_number": 45645511, "upc": "00490000486", "price": 1.00, "tax": 0.08 } 如果客户寄给我的是销售税而不是预期税,我应该退还什么。现在,我要退

我正试图找出在我正在使用的REST类API的不同场景中返回的正确状态代码。假设我有一个端点,允许以JSON格式发布购买。看起来是这样的:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}
如果客户寄给我的是销售税而不是预期税,我应该退还什么。现在,我要退400。但是,我已经开始质疑自己了。我真的应该退422吗?我的意思是,它是受支持的JSON,并且是有效的JSON,它只是不包含所有必需的字段。

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

由于格式错误,服务器无法理解该请求 语法。客户机不应在没有通知的情况下重复请求 修改

422不可处理实体由RFC 4918-WebDav定义。请注意,与400相比存在细微差异,请参见下面引用的文本

如果XML 请求正文包含格式良好的内容,即语法正确,但 语义错误的XML指令

为了保持统一的接口,您应该仅在XML响应的情况下使用422,并且还应该支持Webdav扩展定义的所有状态代码,而不仅仅是422

另见马克·诺丁汉关于状态代码的帖子:

试图“深入”地映射应用程序的每个部分是错误的 转换成HTTP状态码;在大多数情况下,粒度级别 想要达到的目标要粗得多。如果有疑问,可以使用 通用状态代码为200 OK、400 Bad Request和500 Internal 没有更好的匹配时出现服务错误

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

在你提出问题和我最初的回答时,这不是一件事;在这一点上,我反对400个错误的请求,因为我强调说:

由于语法错误,服务器无法理解该请求

您描述的请求是语法有效的JSON,封装在语法有效的HTTP中,因此服务器对请求的语法没有问题

然而:

400 Bad Request status(错误请求状态)代码表示服务器无法或不会处理请求,原因是被认为是客户端错误,例如,请求语法错误、请求消息帧无效或欺骗性请求路由

然而,在重新措辞之前,或者如果您想质疑RFC 7231目前只是一个提议的标准,422不可处理实体对于您的用例来说似乎不是一个不正确的HTTP状态代码,因为

而HTTP/1.1提供的状态代码足以 描述WebDAV方法遇到的大多数错误情况,如下所示 有些错误不属于现有类别。 本规范定义了为WebDAV开发的额外状态代码 方法第11节

并说:

422不可处理实体状态代码表示服务器 了解请求实体的内容类型,因此 415不支持的媒体类型状态代码不正确,并且 请求实体的语法是正确的,因此请求是错误的 状态代码不适当,但无法处理包含的 指示

注意对语法的引用;我怀疑7231也部分淘汰了4918

这听起来和你的情况一模一样,但为了防止有任何疑问,它接着说:

例如,如果XML 请求正文包含格式良好的内容,即语法正确,但 语义错误的XML指令

用JSON替换XML,我认为我们可以同意这是您的情况

现在,一些人会反对RFC4918是关于Web分布式创作和版本控制WebDAV的HTTP扩展,并且您可能没有做任何涉及WebDAV的事情,所以不应该使用它

考虑到在原始标准中使用错误代码(显式地不包括这种情况)和在扩展中使用错误代码(精确地描述这种情况)之间的选择,我会选择后者

此外,参考,其中可以找到422

我建议HTTP客户机或服务器使用该注册表中的任何状态代码是完全合理的,只要它们正确地这样做


但是从HTTP/1.1开始,它有牵引力,所以只需使用400个坏请求

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

始终使用响应代码 在响应正文中包含尽可能多的附加信息,以帮助使用API的开发人员了解发生了什么= 在所有人都因为我说这里没有对错答案而责怪我之前, 让我解释一下我是如何得出这个结论的

在这个特定的示例中,OP的问题是关于一个JSON请求,该请求包含一个与预期不同的键。现在,从自然语言的角度来看,收到的密钥名称与预期的密钥非常相似,但严格来说,它是不同的,因此机器通常不会将其视为等价的

正如我上面所说的,决定因素是什么是语法。如果发送的请求的内容类型为application/json,那么是的,请求在语法上有效,因为它是有效的json语法,但在语义上无效,因为它与预期的不匹配。假设有一个严格的定义,说明什么使得所讨论的请求在语义上有效或无效

另一方面,如果发送请求时使用了更具体的自定义内容类型,比如application/vnd.mycorp.mydatatype+json,它可能精确地指定了所需的字段,那么我会说请求很容易在语法上无效,因此会出现400响应

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}
HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}
HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}
在本例中,由于键是错误的,而不是值,因此如果存在有效键的规范,则会出现语法错误。如果没有有效密钥的规范,或者错误带有值,那么这将是一个语义错误。

为了反映截至2015年的状态:

从行为上讲,400和422响应代码将被客户和中介机构视为相同的代码,因此实际上,您使用的代码并没有具体区别

然而,我希望看到400目前被更广泛地使用,此外,该文件提供的澄清使其成为两种状态代码中更合适的一种:

HTTPbis规范澄清了400的意图,即不只是用于语法错误。更宽泛的短语表示服务器无法或将不会处理请求,因为现在使用了一些被认为是客户端错误的东西。 422是一个WebDAV扩展,在RFC 2616或更新版本中未被引用。 就上下文而言,HTTPbis是HTTP/1.1规范的修订版,试图澄清不清楚或不一致的领域。一旦达到批准状态,它将取代RFC2616。

您的案例:从REST的角度来看,HTTP 400是您案例的正确状态代码,因为它在语法上不正确,无法发送销售税而不是税,尽管它是一个有效的JSON。这通常是大多数服务器端框架在将JSON映射到对象时强制执行的。然而,有些REST实现会忽略JSON对象中的新键。在这种情况下,服务器端可以强制执行只接受有效字段的自定义内容类型规范

422的理想场景:

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

400人超过422人的情况:

请记住,响应代码422是一个扩展的HTTP WebDAV状态代码。仍然有一些HTTP客户端/前端库没有准备好处理422。对他们来说,简单到HTTP 422是错误的,因为它不是HTTP。从服务的角度来看,400不是很具体

在企业体系结构中,服务主要部署在SOA、IDM等服务层上。它们通常服务于多个客户机,从非常旧的本机客户机到最新的HTTP客户机。如果其中一个客户机不处理HTTP 422,那么可以选择要求客户机为每个人将响应代码升级或更改为HTTP 400。根据我的经验,这在现在是非常罕见的,但仍然是可能的。因此,在决定HTTP响应代码之前,始终需要仔细研究您的体系结构

为了处理类似的情况,服务层通常对严格HTTP一致性客户端使用版本控制或设置配置标志发送400,对其余客户端发送422。通过这种方式,它们为现有消费者提供向后兼容性支持,但同时为新客户机提供使用HTTP 422的能力

最新更新内容如下:


这确认服务器可以为无效请求发送HTTP 400。400不再只是指语法错误,但是,只要客户端能够处理,422仍然是一个真正的响应

您应该实际返回200 OK,并在响应正文中包含一条消息,说明发布的数据发生了什么。然后由应用程序来理解消息

问题是,HTTP状态码正是HTTP状态码。这些都意味着只有在传输层才有意义,而不是在应用层。应用程序层甚至不应该知道正在使用HTTP。如果您将传输层从HTTP切换到信鸽,则它不会影响应用程序层 多愁善感

让我给你一个非虚拟的例子。假设你爱上了一个女孩,她也爱你,但是她的家人搬到了一个完全不同的国家。她给了你她新的蜗牛邮箱地址。当然,你决定给她寄一封情书。所以你写你的信,把它放进信封,在信封上写上她的地址,贴上邮票,然后寄出去。现在让我们来考虑这些场景

你忘了写街道名。您将收到一封未拆封的回信,信上写着地址格式错误的消息。你把请求搞砸了,收件邮局无法处理。这相当于收到400个错误请求。 所以你确定了地址,然后再发一次信。但是由于运气不好,你把街道的名字拼错了。你会再次收到这封信,信中会有一条信息说,地址不存在。这相当于接收404未找到。 您再次修复了地址,这次您成功地正确写入了地址。你的女朋友收到信后给你回信。这相当于收到200个OK。然而,这并不意味着你会喜欢她在信中写的东西。这仅仅意味着她收到了你的信息,并对你做出了回应。直到你打开信封读了她的信,你才知道她是非常想念你还是想和你分手。 简言之:返回200 OK并不意味着服务器应用程序对您有好消息。这只意味着它有一些新闻

注:422状态代码仅在WebDAV上下文中有意义。如果您不使用WebDAV,那么422与任何其他非标准代码都具有完全相同的标准含义=无

422未加工实体解释更新日期:2017年3月6日

什么是422不可处理实体

但是,如果请求格式正确,则会出现422状态代码 对于语义错误,无法对其进行处理。此HTTP状态为 在RFC4918中引入,更具体地针对HTTP Web分布式创作和版本控制WebDAV的扩展

关于开发人员是否参与开发,存在一些争议 应向客户端返回400 vs 422错误,更多关于差异的信息 在以下两种状态之间。然而,在大多数情况下,这是一致的 之后,只有在支持WebDAV的情况下才应返回422状态 能力

422状态代码的逐字定义取自第节 RFC 4918中的11.2如下所示

422不可处理实体状态代码表示服务器 了解请求实体的内容类型,因此 415不支持的媒体类型状态代码不正确,并且 请求实体的语法是正确的,因此请求是错误的 状态代码不适当,但无法处理包含的 指示

该定义接着说:

例如,如果XML请求主体 包含格式良好的,即语法正确,但语义正确 错误的XML指令

400对422状态代码

错误的请求错误使用400状态代码,应该 如果请求语法格式不正确,则返回给客户端,包含 无效的请求消息帧,或具有欺骗性的请求路由。 此状态代码可能与422不可处理状态代码非常相似 然而,实体状态是一小部分信息 区别于它们的是,请求实体的语法 422错误是正确的,而生成 400错误是不正确的

422状态的使用只应保留给非常特殊的用户 用例。在大多数其他情况下,由于 对于格式错误的语法,应使用400错误请求状态


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

400错误请求-当请求中缺少关键信息时 e、 g.授权标头或内容类型标头。这是服务器理解请求所必需的。这可能因服务器而异

422不可处理实体-无法解析请求正文时。 这比400严重。请求已到达服务器。服务器已确认请求的基本结构正确。但是请求主体中的信息无法解析或理解

e、 g.内容类型:请求主体为JSON时的application/xml

下面是一篇列出状态代码及其在RESTAPI中的使用的文章。 案例研究:GitHub API

也许从著名的API复制是一个明智的想法:

接收请求主体的API调用上可能存在三种类型的客户端错误:

发送无效的JSON将导致400错误的请求响应

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}
HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}
HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}
发送错误类型的JSON值将导致错误的请求响应

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}
HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}
HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}
结束无效字段将导致422个不可处理的实体响应

HTTP/1.1 400 Bad Request
Content-Length: 35

{"message":"Problems parsing JSON"}
HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}
HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}


你的答案422的可能副本对我来说很有意义。这也是Rails在由于验证错误而无法处理资源时使用的方法。请注意,在非WebDAV规范中使用了422:作为一个更新,RFC 7231对响应代码400有不同的描述,这改变了语义。很抱歉,我更新了此答案以反映RFC中的更改,并失去了一些清晰度;我将尝试重构。使用422几乎可以肯定是安全的,但现在你应该使用400。我仍然认为规格可能更清晰。中给出的示例是客户做错事的明显案例。OP的情况也属于这一类。然而,有些情况下,我理解你的要求,但我拒绝这样做,因为有一些商业规则不那么明确。这并不完全是客户机的错误,因此根据相同的规范,403可能实际适用:但是,请求可能由于与凭据无关的原因而被禁止。我更愿意为权限相关的东西使用单独的代码,而不是无法完成。422代码是IANA注册表的一部分,所以任何IMHO都没有意义。在任何情况下,Facebook和Twitter REST API都会重新设计自己的代码,而不使用RFC/IANA标准。所以你可以这样做。第11节特别说明它们被添加到整个规范中,而不仅仅是在WebDav规范中:以下状态代码被添加到HTTP/1.1[RFC2616]中定义的状态代码中。仅仅因为这些代码被描述为WebDav规范的一部分并不意味着它是WebDav特定的!状态代码应该是通用的。那么403禁止的代码是否也可以用于此上下文?Quote:403禁止状态代码表示服务器理解该请求,但拒绝对其进行授权…如果请求中提供了身份验证凭据,则服务器认为这些凭据不足以授予访问权限…但是,请求可能由于与凭据无关的原因而被禁止。看来403可以用来拒绝身份验证之外的请求。@garbagecollector注意,被拒绝的原因不在凭据范围内!=由于身份验证以外的原因被拒绝。有很多方法可以不使用凭据对某人进行身份验证,特别是。@garbagecollector否,凭据意味着身份验证您是谁,失败时将是401。授权失败后,您能做的是403。此处的完整解释:这两种情况都不适用于OP的缺少字段的情况,因为无论是哪个用户尝试此操作,错误都是相同的。我同意400是正确的答案。答案被低估了-谢谢你的解释。这正是我对这件事的想法!我来自XMLSOAP背景,模式的概念刚刚进入我的血液,JSON文档并没有公布它们的模式。对我来说,关键在于服务器是否理解请求。如果服务器不知道什么是销售税,那么它就是400:我不知道你给我发了什么,但肯定不是我想要的。422表示语法有效,但内容无效。在需要XML的地方发送JSON意味着语法错误,因此在这种情况下,400是正确的响应。正如Dirk所说,422意味着语法上有效的请求可以被解析和理解,但语义上无效400:当请求因为无效语法(例如解析错误)而无法处理时;422:由于无效数据(例如验证错误)而无法处理请求时。您的422示例无效,因为通过发送带有应用程序/xml媒体类型的json,正文自动在语法上不正确,响应应为400。我认为这是正确且可理解的答案。无法再对此进行投票。我希望更多的投票结果会涉及到这一点。规范RFC,IANA epically未能提供明确的定义和两者之间的区别。所以答案归结为最佳实践,GitHub给了我们一个答案。这必须是公认的答案。此外,答案中提供的url不再有效,会将您带到主页。最新的url是:。