协慌网

登录 贡献 社区

资源已经存在时 POST 的 HTTP 响应代码

我正在构建一个允许客户端存储对象的服务器。这些对象在客户端完全构建,并带有在对象整个生命周期中永久存在的对象 ID。

我已经定义了 API,以便客户端可以使用 PUT 创建或修改对象:

PUT /objects/{id} HTTP/1.1
...

{json representation of the object}

{id} 是对象 ID,因此它是 Request-URI 的一部分。

现在,我也在考虑允许客户端使用 POST 创建对象:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

由于 POST 是 “附加” 操作,因此如果对象已经存在,我不确定该怎么做。我应该将请求视为修改请求,还是应该返回一些错误代码(哪个)?

答案

我的感觉是409 Conflict是最适当的,但是在野外很少见到:

由于与资源的当前状态存在冲突,因此无法完成请求。仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许使用此代码。响应主体应该包含足够的信息,以使用户能够识别冲突的根源。理想情况下,响应实体应包括足够的信息以供用户或用户代理解决问题。但是,这可能是不可能的,也不是必需的。

响应 PUT 请求最有可能发生冲突。例如,如果正在使用版本控制,并且正在 PUT 的实体包括对资源的更改,该更改与先前的(第三方)请求所做的更改冲突,则服务器可能会使用 409 响应来指示它无法完成请求。在这种情况下,响应实体可能会以响应 Content-Type 定义的格式包含两个版本之间差异的列表。

根据RFC 7231如果处理 POST 的结果等效于现有资源的表示,则可以使用303 See Other

我个人使用 WebDAV 扩展422 Unprocessable Entity

根据 RFC 4918

422 Unprocessable Entity状态代码表示服务器理解请求实体的内容类型(因此415 Unsupported Media Type状态代码不合适),并且请求实体的语法正确(因此400 Bad Request状态代码不合适)但无法处理其中包含的说明。