我正在构建一个允许客户端存储对象的服务器。这些对象是在客户端完全构造的,对象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意味着“追加”操作,我不确定在对象已经存在的情况下该做什么。我应该把请求作为修改请求,还是应该返回一些错误代码(哪个)?


当前回答

错误402,需要付款

例如,这个资源已经存在,但如果你给我足够的钱,我会删除当前的一个,给你:D

...但是看看mozilla在https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses上对状态码的定义

作为一个更严肃的答案,这里没有人提供,那451呢:由于法律原因无法使用。你不能“合法地(通过你自己制定的条款和条件)”让多人访问相同的帐户信息

422也是一个很好的选择,它是不可处理的实体 请求格式良好,但由于语义错误而无法执行。由于它是一个完全有效的请求,但由于它在语义上与另一个条目相等,所以不能遵循它。

其他回答

我觉得你不应该这么做。

如您所知,POST用于修改集合,并用于CREATE一个新项。所以,如果你发送id(我认为这不是一个好主意),你应该修改集合,即,修改项目,但这是令人困惑的。

使用它添加一个项目,没有id。这是最好的做法。

如果您想捕获一个UNIQUE约束(而不是id),您可以响应409,就像在PUT请求中一样。但不是身份证。

根据RFC 7231,如果POST处理的结果等同于 现有资源的表示。

我的感觉是409冲突是最合适的,但是,在野外当然很少见到:

The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.

我会选择422不可处理实体,当请求无效时使用,但问题不在于语法或身份验证。

作为反对其他答案的论据,使用任何非4xx错误代码将暗示它不是客户端错误,而它显然是。使用非4xx错误代码来表示客户端错误完全没有意义。

It seems that 409 Conflict is the most common answer here, but, according to the spec, that implies that the resource already exists and the new data you are applying to it is incompatible with its current state. If you are sending a POST request, with, for example, a username that is already taken, it's not actually conflicting with the target resource, as the target resource (the resource you're trying to create) has not yet been posted. It's an error specifically for version control, when there is a conflict between the version of the resource stored and the version of the resource requested. It's very useful for that purpose, for example when the client has cached an old version of the resource and sends a request based on that incorrect version which would no longer be conditionally valid. "In this case, the response representation would likely contain information useful for merging the differences based on the revision history." The request to create another user with that username is just unprocessable, having nothing to do with any version conflict.

为了记录,422也是GitHub使用的状态码,当您尝试按已使用的名称创建存储库时。

在检查重复记录的正确代码时偶然发现了这个问题。

请原谅我的无知,但我不明白为什么每个人都忽略了代码“300”,它清楚地表示“多项选择”或“模棱两可”

在我看来,这将是构建非标准或特定系统供自己使用的完美代码。我也可能是错的!

https://www.rfc-editor.org/rfc/rfc7231#section-6.4.1