区分REST中命名资源的创建和更新

时间:2014-04-03 02:37:48

标签: http rest put

我已经阅读了put-vs-post-in-rest,而且我知道PUT用于创建和更新特定资源,并在URL中明确指定标识符。

但是,如果我要严格更新"更新"使用If-Match操作(这意味着用户必须提供有效的ETag来更新资源),假设PUT也用于创建命名资源(不需要If-Match),那么API将不得不猜测是否PUT request是指根据是否提供If-Match标头来更新或创建。

我知道这可以做到,但我认为这很奇怪。是否有其他(更合理)的方法(通过不使用PUT)?

感谢。

更新

以下是我的情景:

# create the resource the first time
curl -X PUT -d '{"foo": "bar"}' /resource/r_id 

# the resource already exists, so this will fail with a 4xx error
curl -X PUT -d '{"foo": "bar2"}' /resource/r_id 

# must provide valid If-Match to make updates work
curl -X PUT -H 'If-Modefied: myetag' -d '{"foo": "bar2"}'  /resource/r_id

# what makes it confusing is this:
# user want to make a new record, but /resource/r_id2 in fact exists
# the API will return an error message, should it be
# "creation failed -- already exist" or "update failed -- ETag not provided"?
curl -X PUT -d '{"foo": "bar"}' /resource/r_id2

并不是说不能这样做,只是因为我认为这个设计(对于ETag控制的更新和命名创建都有PUT)可能会令人困惑,我个人认为如果我使用不同的词汇(不仅仅是PUT),它会更好,但是,我在这里询问我能做到的合理和RESTful方式是什么。

3 个答案:

答案 0 :(得分:2)

您可以使用“If-None-Match:*”保护PUT-to-create,请参阅http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p4-conditional-26.html#rfc.section.3.2.p.7

此外,您可能需要考虑使用http://greenbytes.de/tech/webdav/rfc6585.html#status-428

答案 1 :(得分:1)

您可以尝试模仿设计良好的REST API。

对于this feature,CouchDB设计师选择以409 Conflict作为状态,{"error":"conflict","reason":"Document update conflict."}作为正文。

Nota bene :删除"文档"当然,因为它是特定的应用程序。

答案 2 :(得分:0)

您不需要使用If-Match限制更新。当您获得PUT时,请检查您的数据存储区。如果具有给定id的资源尚未存在,请创建它。如果是,请将其更新为具有给定值。

If-Match购买的内容是确保资源未在数据存储中更改。你试图避免这种情况:

client 1: GET /resources/1
client 2: GET /resources/1
client 2: PUT /resources/1 with updates
client 1: PUT /resources/1 with updates