为用户与其他实体交互构建 URL 的 RESTful 方式是啥?
Posted
技术标签:
【中文标题】为用户与其他实体交互构建 URL 的 RESTful 方式是啥?【英文标题】:What's the RESTful way to structure an URL for user interactions with other entities?为用户与其他实体交互构建 URL 的 RESTful 方式是什么? 【发布时间】:2012-07-19 17:44:38 【问题描述】:我正在尝试找出正确的 RESTful 方式来构建用户与其他实体交互的 URL?
例如,我有三个实体:users
、posts
和 tags
。
如何表示“用户点赞帖子”、“用户关注标签”或“用户关注用户”。
这是我的想法,但我不确定这是否是正确的做法:
POST /user/:id/like/post/:id
(用户点赞)
POST /user/:id/follow/user/:id
(用户关注另一个用户)
看起来很语义化,但我不确定 POST 方法
【问题讨论】:
【参考方案1】:公平警告:我也是 REST 新手。
一些一般性评论,摘自 Leonard Richardson 和 Sam Ruby 的 RESTful Web Services:
资源名称使用复数 如果服务器控制资源的身份,则对资源名称使用 POST 如果客户端控制资源的身份,则对资源/:id 使用 PUT将其应用于您的情况,我可以看到以下资源
/users : 用户列表 /users/id : 特定用户 /users/id/tags : 此特定用户使用的标签列表 /users/id/posts : 此特定用户喜欢的帖子列表 /users/id/follows : 该特定用户关注的用户列表要将帖子添加到用户喜欢的帖子中,我将发布到/users/id/posts
并标识要添加到请求正文中喜欢的帖子列表中的帖子。
类似于记录用户 1 现在也关注用户 200 和 300,我会在请求正文中使用这些用户的标识 POST 到 /users/id/follows
。
毕竟,您没有提供用户 1 和其他两个用户之间关系的标识,而是添加了两个新的关系资源,分别具有用户 200 和用户 300 作为其“关注用户”属性。
支持您的应用的数据库很可能有一个 Users 表、一个 Posts 表和一个 Likes,其中 Likes 表是您记录用户喜欢 Post 时添加的表。并且点赞记录的标识不会是用户的标识,也不是帖子的标识,而是有自己的标识(单独或作为用户和帖子标识的组合)。
即使您将用户点赞的帖子存储在关系模型之外的其他东西中,甚至可能没有单独的点赞标识,每个点赞的标识仍然是用户和帖子的组合。
【讨论】:
很好的解释。谢谢。我知道旧帖子,但我认为 /users/id/posts 需要保留以获取属于该用户的所有帖子,因此不需要额外的 /users/id/likes 路线是吗? @isimmons: 是的,如果您将/users/id/posts
用于 用户的所有帖子,那么/users/id/likes
是帖子的一个选项(可能是其他人?)用户已收藏/加星标/其他。有些人会争辩说可以使用查询参数。我认为返回资源的语义决定/何时需要不同的 URI。用户创作的帖子与任何人创作并被用户标记为喜欢的帖子完全不同。【参考方案2】:
RESTful 接口有一个众所周知的 URL 作为起点。响应中提供的超媒体控件应从那里访问所有其他操作和实体。从这个意义上说,URL 结构根本不重要,对客户端也不重要。它们可能是完全不透明的(例如,http://bit.ly/9xhUgg),客户端仍然可以工作。
这里有一些有用的阅读:
Richardson Maturity Model A RESTful Hypermedia API in Three Easy Steps话虽如此,从服务器实现的角度来看,使用您建议的结构会更容易。比如:
GET /
<myapplication href="/">
<users href="/users"/>
<posts href="/posts"/>
<tags href="/tags"/>
</myapplication>
GET /users
<users href="/users">
<user username="johndoe" href="/users/1234"/>
<user username="janedoe" href="/users/1235"/>
<next href="/users?page=2"/>
<search href="/users">
<name type="string" cardinality="required"/>
</search>
</users>
GET /users?page=2
<users href="/users">
<user username="bobgeldof" href="/users/1236"/>
<user username="biancajager" href="/users/1237"/>
<next href="/users?page=3"/>
<prev href="/users"/>
<search href="/users">
<name type="string" cardinality="required"/>
</search>
</users>
GET /users/1236
<user username="bobgeldof" href="/users/1236">
<posts-liked href="/users/1236/posts"/>
<tags-followed href="/users/1236/tags"/>
<users-followed href="/users/1236/users"/>
<like-post href="/users/1236" method="PUT">
<post type="URL" cardinality="required"/>
</like-post>
<follow-tag href="/users/1236" method="PUT">
<tag type="URL" cardinality="required"/>
</follow-tag>
<follow-user href="/users/1236" method="PUT">
<user type="URL" cardinality="required"/>
</follow-user>
</user>
重要的一点是,当一篇文章被点赞、标签或用户被关注时,文章、标签或用户的 URI 是作为参数提交的,而不是 ID。顺便说一句,我将 PUT 用于这些操作的原因是该操作是幂等的。如果不是,我会改用 POST。
GET /users/1236/posts
<liked-posts href="/users/1236/posts">
<post href="http://***.com/questions/11566436" title="What's the RESTful way to structure an URL for user interactions with other entities?">
<unlike href="/users/1236/posts?href=http%3A%2F%2F***.com%2Fquestions%2F11566436" method="DELETE"/>
</post>
...
<next href="/users/1236/posts?page=2"/>
</liked-posts>
GET /users/1236/users
<followed-users href="/users/1236/users">
<user username="biancajager" href="/users/1237">
<unfollow href="/users/1236/users?href=%2Fusers%2F1237" method="DELETE">
</user>
<user username="Jorge Pedret" href="http://***.com/users/201092/jorge-pedret">
<unfollow href="/users/1236/users?href=http%3A%2F%2F***.com%2Fusers%2F201092%2Fjorge-pedret" method="DELETE"/>
</user>
<next href="/users/1236/users?page=2"/>
</followed-users>
我真正喜欢上述内容的一点(除了它是真正的 RESTful 之外)是因为您使用的是 URL 而不是 ID,所以您可以喜欢和关注其他系统中的帖子和用户。 :)
【讨论】:
以上是关于为用户与其他实体交互构建 URL 的 RESTful 方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章