我有一个RESTFul API,其资源代表键的设置引用。
我有一个操作是将一个元素作为PUT添加到集合中,其URI是api/Aggregation/{key}
。
销毁该集合的操作是DELETE,其URI为api/Aggregation/{key}
。
但是如果我想从集合中删除一个元素,我必须使用哪个动词?
我曾考虑使用PUT操作并在正文中添加一个值来指示我是否正在删除或添加元素,但我不知道它是否是Restful设计的最佳实践。
答案 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谓词以指出即将采取的正确操作。
亲切的问候,