Restful API:在没有封闭实体的情况下发送PUT是否有意义?

时间:2016-02-02 01:12:53

标签: rest asp.net-web-api

考虑以下情况:

现有两个实体:shopping card #1item #1。我想将item #1添加到shopping card #1。有两种方法可以设计Restful api

1 没有身体:

PUT http://myshoppingsite.com/api/shoppingcards/1/items/1
Host: myshoppingsite.com

2:使用正文(包含实体):

PUT http://myshoppingsite.com/api/shoppingcards/1/items/
Host: myshoppingsite.com    

{itemId: "1"}

实际上,我无法确定哪一个更好,而且在休息方面更有意义。有什么想法吗?

注意:我认为http方法应该是PUT因为幂等性,但这不是我的问题。)

PS:我对第一个设计的问题是请求中没有此类enclosed entity。语言上的put是一个及物动词,所以我希望有人put s 某事。我认为同样的故事不知何故在HTTP世界中。

1 个答案:

答案 0 :(得分:1)

PUT是一个HTTP动词,应该创建或替换目标URI,因此这会使您的第一个选项立即出错。此请求替换所有购物车中的商品:

PUT http://myshoppingsite.com/api/shoppingcards/1/items/

由于您想添加某些东西到您的购物车,这不是一个选项。这实际上留下了两个选择。第一:共同的:

POST http://myshoppingsite.com/api/shoppingcards/1/items/

POST可能意味着许多事情,但在REST服务的上下文中,它通常用于将某些内容附加到集合中。但是,你提到你想要幂等。这里有两个选项,首先你可以仍然使用POST,并且在API的上下文中保证请求 是幂等的。使用POST并不意味着它的每个定义都是非幂等的,它只是意味着仅仅HTTP规范并不能保证它。这并不妨碍使请求具有幂等性。

另一个选项确实是PUT

PUT http://myshoppingsite.com/api/shoppingcards/1/items/1

您对此有疑虑,因为在API的上下文中,您说请求正文最终会为空。

这样做的原因是你在网址的最后/1附加了特殊内容,我觉得这有什么不对。如果您想遵循REST最佳实践,那么网址不应该有任何特殊含义。

我认为,如果你坚持使用PUT,那么做一个更健全的方法就是摆脱“一个id”的概念。该概念仅存在于您的数据库中,不应该进入API。

相反,我认为您的服务有一个产品列表,例如:

http://myshoppingsite.com/products/1

要使用PUT将商品添加到购物车,此请求可能如下所示:

PUT http://myshoppingsite/api/shoppingcards/1/items/[completely-arbitrary-string-or-perhaps-a-uuid]
Content-Type: application/json

{
   "product" : "http://myshoppingsite.com/products/1",
   "quantity" : 5
}

就个人而言,我只会使用POST

问:应该有关于您添加的产品的一些信息,不是吗?是的,该信息是Uril的一部分。为什么不好?

我不是说这很糟糕,我说这不是RESTful。拿起任何关于REST的书,你会看到这个确认。这也许是开始阅读有关REST的更多内容的好地方:

http://martinfowler.com/articles/richardsonMaturityModel.html

我个人会说,很少有人构建真正的RESTful服务。这就是为什么我还要特别指出我不想说这对你的特定API是坏的或好的,它根本就不是RESTful。

如果我不关心这些原则并希望保留我的特殊意义网址计划怎么办?

那是一个公平的观点,但是我们已经超越了原来的问题了。如果你想设计一个API,其中网址的最后一位实际上是购物车中商品的“表示”,那么我同意在主体中是多余的。< / p>

在那种情况下,我会说,保持请求体空。我猜是不要把它称为REST。