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


当前回答

另一个潜在的治疗方法是使用PATCH。PATCH被定义为改变内部状态的东西,不局限于追加。

PATCH将通过允许您更新已经存在的项目来解决这个问题。参见:RFC 5789: PATCH

其他回答

用户侧故障,属于4xx组。这是正确答案https://developers.rebrandly.com/docs/403-already-exists-errors

我觉得你不应该这么做。

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

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

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

I think for REST, you just have to make a decision on the behavior for that particular system in which case, I think the "right" answer would be one of a couple answers given here. If you want the request to stop and behave as if the client made a mistake that it needs to fix before continuing, then use 409. If the conflict really isn't that important and want to keep the request going, then respond by redirecting the client to the entity that was found. I think proper REST APIs should be redirecting (or at least providing the location header) to the GET endpoint for that resource following a POST anyway, so this behavior would give a consistent experience.

EDIT: It's also worth noting that you should consider a PUT since you're providing the ID. Then the behavior is simple: "I don't care what's there right now, put this thing there." Meaning, if nothing is there, it'll be created; if something is there it'll be replaced. I think a POST is more appropriate when the server manages that ID. Separating the two concepts basically tells you how to deal with it (i.e. PUT is idempotent so it should always work so long as the payload validates, POST always creates, so if there is a collision of IDs, then a 409 would describe that conflict).

更有可能是400个坏请求

[* * 6.5.1。400错误请求**][1]

400(坏请求)状态代码表示服务器不能或 将不会处理请求由于某些东西被认为是 客户端错误(例如,格式错误的请求语法,无效的请求 消息框架,或欺骗性请求路由)。

由于请求包含重复的值(已经存在的值),因此可以将其视为客户机错误。需要在下次尝试之前更改请求。 通过考虑这些事实,我们可以得出HTTP STATUS 400错误请求的结论。

由于您提到使用post的对象创建请求包含对象的ID,因此应该使其成为幂等请求。只返回与成功创建请求完全相同的响应。幂等请求使api更简单,例如。现在客户不必担心两种不同的情况(成功,失败)。或者客户端可以安全地重试请求,以防在连接/服务器暂时宕机时出现问题。