由于现有匹配资源,资源创建 POST 失败时的 HTTP 响应代码

Posted

技术标签:

【中文标题】由于现有匹配资源,资源创建 POST 失败时的 HTTP 响应代码【英文标题】:HTTP response code when resource creation POST fails due to existing matching resource 【发布时间】:2014-10-21 20:49:03 【问题描述】:

假设我们有一个 API,可以通过 POST 创建一个新员工

www.example.com/api/employees

员工可以被描述为,


  name: "John Smith",
  tax_number: "ABC123"

税号对所有人来说都是独一无二的。如果进行了创建,并且已经存在名称和税号与现有记录匹配的记录,则可以安全地假设请求者希望返回对该记录的引用(使用它的内部 id 和其他数据,客户可能不会例如,创建于,更新于)。

返回该资源的 HTTP 状态代码是什么?我想重定向可以与仅返回 id 一起使用,但我更愿意将整个对象包含在响应中。

这种情况是一个简单的重复错误所独有的,从某种意义上说,如果尝试重复,则意味着您希望创建的记录已经存在——而不是它与现有记录发生冲突。

【问题讨论】:

REST HTTP status codes for failed validation or invalid duplicate 的可能重复项 但另见HTTP response code for POST when resource already exists。 【参考方案1】:

我认为,如果您将资源发布到 API,您期望代码 201 表明该资源已创建,并且正文将(可以)包含该资源。 否则,您首先必须检查资源是否已创建,但这需要两次调用。

否则,您的状态码为 409:

由于与资源的当前状态冲突,请求无法完成。

[编辑]在阅读 amundsen、Ruby 和 Richardson 的 Restfull Web APIs 之后

最好使用 409 状态代码,表明与服务器上存在的资源存在冲突。将该“冲突”资源的 url 放在响应的 Location Header 中,并在正文中添加冲突消息

【讨论】:

来自 HTTP/1.1 规范:“此代码仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许使用。”。我认为这并不适合这种情况。 但在这里他尝试创建一个 tax_number 与后端已创建的另一个资源相同的资源。因此消息可能会返回与已创建的另一个资源发生冲突并返回正文中已创建的资源。但这也可以通过 403 状态码来完成,该状态码禁止具有相同的错误消息。 对,但是对于409,消费者如何解决冲突?他们不能很好地去改变这个人的税号,不是吗? :D 真的,除了向用户显示失败原因的错误外,什么都做不了。 409状态有冲突,在返回体中,他可以有冲突的资源。但如果 409 不可接受,那么我会选择 403 禁止而不是 500,至于我 500 状态码说明代码有问题,或者未处理异常或其他内部缺陷 我认为在这种情况下要解决 409,客户端应用程序需要显示一条消息,说明现有税号已经存在,并且他们希望更新现有资源。解决冲突并不意味着您需要再次尝试相同的方法,在这种情况下,如果用户想要编辑,请获取税号的最新副本,然后 PUT 更改【参考方案2】:

有一个409 Conflict 响应代码,通常用于让客户端知道服务器上已经存在这样的实体。必须解析错误响应的正文可能不是很直观,但如果您在 API 文档中指定这一点,则应该没有问题(将有关原始条目的信息放入响应正文中)。

【讨论】:

以上是关于由于现有匹配资源,资源创建 POST 失败时的 HTTP 响应代码的主要内容,如果未能解决你的问题,请参考以下文章

POST与PUT

如何在现有 C++ 项目中添加对话框资源

登录/注册表单的 REST 资源

用于创建资源的 REST API 补丁方法

REST API 设计 - 最佳实践:链接现有子资源 [关闭]

Rails 资源路由缺少参数但匹配文档