更新REST API中的单个属性

时间:2014-02-20 14:26:39

标签: api rest

在设计新API时,我们正在尽力遵循REST建立的模式。我遇到的问题是尝试更新单个属性时要遵循的最佳方法。例如:

想象一下,你有一个简单的汽车资源:

{
   "make": "Chevrolet",
   "model": "Chevelle",
   "year": 1966,
   "color": "black",
   "for_sale": true
}

我们假设属性for_sale是您预期将由用户定期更新的内容。我有几个选择:

  1. PUTfor_sale设置为false的整个资源。对于一个相当小的资源,这似乎很好,但是,在大多数情况下,我们的资源非常庞大,因此在发送整个资源以更新单个(通常是更改的)属性时会浪费很多。

  2. POST并通过仅包含要更新的元素进行部分更新,例如: {"for_sale":false}这样做更好,因为它需要更少的开销。

  3. 但我似乎在某种程度上寻求更简单的东西,但我似乎找不到合适的方法。向URL(不需要任何请求体)提供简单的PUT来更新此属性会非常方便。我看到谷歌在他们的API中做了什么来实现这一点,但感觉有点像RPC-ish,虽然我喜欢简单。

    POST /blogs/blogId/posts/postId/comments/commentId/approve (将评论标记为非垃圾邮件)

    POST /blogs/blogId/posts/postId/comments/commentId/spam(将评论标记为垃圾内容)

    有人可以提供一些建议来了解更新资源中的单个属性(以优选的轻量级方式)遵循REST原则的最佳方法吗?谢谢!

2 个答案:

答案 0 :(得分:11)

实际上,我认为PATCH方法是专门为此目的而设计的。您应该使用它来提供对象的部分更新,而不是完整更新。 Here is a blog entry更详细地解释了这一点。

答案 1 :(得分:0)

正如你所提到的那样:

PUT将for_sale设置为false的整个资源。对于一个相当小的资源,这似乎很好,但是,在大多数情况下,我们的资源非常大,因此在发送整个资源以更新单个(通常是已更改的)属性时会浪费很多。

这是事实,因此对于这种情况,我会提出以下方法:

URI应该是这样的:

POST /api/cars/C1234

Request Body: {"for_sale":false} 由于并非所有的Web服务器(以及忘记客户端)都支持PATCH,因此人们一直支持使用POST进行部分更新:

这仍然不是完美的RESTful API设计,但我已经看到并遵循这个作为最佳实践。