更新RESTFul资源添加元素或从其集合中删除元素,都是PUT操作吗?

时间:2018-01-18 07:37:19

标签: rest

我有一个RESTFul API,其资源代表键的设置引用。

我有一个操作是将一个元素作为PUT添加到集合中,其URI是api/Aggregation/{key}

销毁该集合的操作是DELETE,其URI为api/Aggregation/{key}

但是如果我想从集合中删除一个元素,我必须使用哪个动词?

我曾考虑使用PUT操作并在正文中添加一个值来指示我是否正在删除或添加元素,但我不知道它是否是Restful设计的最佳实践。

2 个答案:

答案 0 :(得分:3)

如果这个uri代表你的集合:

/api/Aggregation/{key}.

然后对它执行PUT请求不会向集合添加任何内容,它会完全替换集合。

您可能想要的是,在另一个资源所代表的集合中有单独的项目,例如:

/api/Aggregation/{key}/{item}

然后,您可以执行PUT请求来创建/替换集合中的项目,然后DELETE删除集合中的项目。

或者,您可以使用POST将新项目附加到集合中。此请求通常会在set url上发生:

POST /api/Aggregation/{key}

这是一种非常常见的模式:

GET    /api/Aggregation/{key}        - to get the entire set.
DELETE /api/Aggregation/{key}        - to delete the entire set.
PUT    /api/Aggregation/{key}        - to replace the set
POST   /api/Aggregation/{key}        - to add something to the set
GET    /api/Aggregation/{key}/{item} - to retrieve a single item
PUT    /api/Aggregation/{key}/{item} - to update an item (or create an item by name)
DELETE /api/Aggregation/{key}/{item} - to delete an item

这可能是最好的' RESTful'做法。如果你不想为集合中的项目创建单独的资源,你可能需要做一些有争议的东西而不是RESTful,比如集合上的PATCH,它比REST更像RPC。

tl; dr:PUT始终完全替换目标URI上的资源。

答案 1 :(得分:0)

我会通过决定PUT和PATCH动词(而不是PUT和DELETE)来解决这个问题。根据RFC 2616,让我们参考PUT和PATCH定义。

PUT在第9.6节RFC 2616中定义:

  

PUT方法请求将所包含的实体存储在   提供了Request-URI。如果Request-URI引用已存在的URI   资源,封闭的实体应该被视为修改过的   驻留在源服务器上的版本。如果是Request-URI   不指向现有资源,并且该URI能够   被请求用户代理定义为新资源   origin服务器可以使用该URI创建资源。

PATCH在RFC 5789中定义:

  

PATCH方法请求中描述的一组更改   请求实体应用于由...标识的资源   Request-URI。

考虑到这一点,我认为从已存在的集合中删除一个元素的正确方法是PATCH动词。例如,如果您的端点创建一个全新的集合,您将使用POST,如果它删除它,您将使用DELETE,但如果它以任何方式更改它(添加新项目或删除特定项目,但不删除/添加整个父母)它应该是PATCH。

现在,这枚硬币的第二面......:)

您可能有多个端点来处理此问题,而某些端点可能会将一个端点视为父级。在这种情况下,POST / DELETE是正确的方法。

总结一下,让我们来看看几个端点......

POST       /myGreatApi/v1/set/create
DELETE     /myGreatApi/v1/set/delete
PATCH      /myGreatApi/v1/set/addElement
PATCH      /myGreatApi/v1/set/removeElement

另一方面,如果您有不同的API结构......

POST      /myGreatApi/v1/set/create
DELETE    /myGreatApi/v1/set/delete
POST      /myGreatApi/v1/set/{id}/element/create
DELETE    /myGreatApi/v1/set/{id}/element/delete
POST      /myGreatApi/v1/element/{id}/addToSet/{id}
DELETE    /myGreatApi/v1/element/{id}/removeFromSet/{id}

考虑到这一切,我认为没有“最佳实践方法”。您的HTTP谓词取决于您决定实施的实际API结构。

总的来说,如果你记录得足够好以便用户能够使用它,那么你做得很好...... :)就良好做法而言,我会一直这样思考: “我是在创建/删除整个父元素,还是在更改(添加,删除)父元素中的子元素?我的API是否正确表示此操作?”

希望你会发现这有用。

注意:正如@Evert在下面评论的那样,在API结构中使用HTTP谓词并不是一种好习惯。上面的示例包含HTTP谓词以指出即将采取的正确操作。

亲切的问候,