我有一个系统,登录用户可以对帖子进行喜欢或不喜欢的投票。如果他们试图喜欢一个已经被喜欢的帖子,他们会删除它的投票。同样适用于不喜欢。作为 REST 新手,我试图为此想出一个 url 方案,但它很令人困惑
目前,我的网址如下
POST /news/vote/social/:feedItemId/:vote(like|dislike|reset)
单个端点可以完成所有操作,登录用户才是真正可以投票的人
在阅读了 stackoverflow 上的一些其他答案后,似乎还有其他可能性,例如
PUT /news/vote/social/:feedItemId/(like|dislike)
DELETE /news/vote/social/:feedItemId
我看过其他答案,其中 userId 也包含在 url 中,因为它说 REST API 设计不应反映有状态
PUT /news/vote/social/feedItemId/:userId/(like|dislike)
DELETE /news/vote/social/:userId/:feedItemId
这些网址的问题是任何人都可以更新任何 userId 的投票,除非涉及某些后端检查
我的问题是,考虑到只有登录的人才能更新他们的投票,处理这些问题的正确方法是什么?
听起来您可能应该看看自定义方法。
由于这是针对每个用户的操作,因此拥有支持投票和反对投票的自定义方法是非常有意义的,其中每个方法都充当 +1 或 -1 的切换。例如:
POST /items/1234:upvote
在新帖子上会添加+1(分=1)POST /items/1234:upvote
再次在同一帖子上将取消投票(分=0)POST /items/1234:downvote
在同一篇文章上再次添加-1(分=-1)POST /items/1234:downvote
再次在同一帖子上将取消否决票(分=0)。一个额外的考虑因素是以下顺序:
POST /items/5678:upvote
会将分数变为 1。POST /items/5678:downvote
之后就会取消赞成票并应用反对票,使分数从 +1 变为 -1。(反之亦然)
您提到这需要一些后端检查,这是绝对正确的。如果您实现的 API 中任何用户都可以应用任何其他用户的赞成票或反对票(只要他们知道用户 ID),那么您就会面临安全风险。因此,处理此问题的正确方法是在登录后使用后端从会话中提取用户 ID(而不是从 URL 中提取,任何人都可以在其中填写他们代表哪个用户投票的空白)的)。
根据RESTful约定,我们不应该根据REST约定使用动词,我们可以简单地使用名词并跟随资源的状态变化
切换:
PUT /items/123/vote
(如果已经投票赞成,则投票反对,否则投票赞成)
或者您可以根据您的资源和数据库设计使用PATCH
分开的动作:
POST /items/123/vote
(投票)DELETE /items/123/vote
(投票否决)
这样您就可以保持 API RESTful