问题描述
目前我正在开发一个 API,在该 API 中,我希望登录用户能够喜欢/不喜欢或喜欢/不喜欢两种资源.
Currently I am developing an API and within that API I want the signed in users to be able to like/unlike or favorite/unfavorite two resources.
我的Like"模型(它是一个 Ruby on Rails 3 应用程序)是多态的,属于两个不同的资源:
My "Like" model (it's a Ruby on Rails 3 application) is polymorphic and belongs to two different resources:
/api/v1/resource-a/:id/likes
和
/api/v1/resource-a/:resource_a_id/resource-b/:id/likes
问题是:我不确定如何选择使我的资源尽可能 RESTful.我已经尝试了接下来的两种方法来在我的 URL 中实现类似/不同的结构:
The thing is: I am in doubt what way to choose to make my resources as RESTful as possible. I already tried the next two ways to implement like/unlike structure in my URL's:
案例 A:(喜欢/不喜欢成为资源"的成员)
Case A: (like/unlike being the member of the "resource")
PUT /api/v1/resource/:id/like maps to Api::V1::ResourceController#like
PUT /api/v1/resource/:id/unlike maps to Api::V1::ResourceController#unlike
和情况 B:(喜欢"是它自己的资源)
and case B: ("likes" is a resource on it's own)
POST /api/v1/resource/:id/likes maps to Api::V1::LikesController#create
DELETE /api/v1/resource/:id/likes maps to Api::V1::LikesController#destroy
在这两种情况下,我都已经有一个用户会话,所以我不必在删除/取消喜欢"时提及相应的喜欢"记录的 ID.
In both cases I already have a user session, so I don't have to mention the id of the corresponding "like"-record when deleting/"unliking".
我想知道你们是如何实施这些案例的!
I would like to know how you guys have implemented such cases!
2011 年 4 月 15 日更新:会话"是指与每个请求一起发送的 HTTP 基本身份验证标头,并提供加密的用户名:密码组合.
Update April 15th, 2011: With "session" I mean HTTP Basic Authentication header being sent with each request and providing encrypted username:password combination.
推荐答案
我认为您在服务器上维护应用程序状态(包含用户 ID 的用户会话)这一事实是这里的问题之一.它使这变得比它需要的要困难得多,并且它打破了 REST 的无状态约束.
I think the fact that you're maintaining application state on the server (user session that contains the user id) is one of the problems here. It's making this a lot more difficult than it needs to be and it's breaking a REST's statelessness constraint.
在案例 A 中,您已经为操作提供了 URI,这又不是 RESTful.URI 标识资源,状态转换应使用所有资源通用的统一接口执行.我认为案例 B 在这方面要好得多.
In Case A, you've given URIs to operations, which again is not RESTful. URIs identify resources and state transitions should be performed using a uniform interface that is common to all resources. I think Case B is a lot better in this respect.
因此,考虑到这两点,我建议如下:
So, with these two things in mind, I'd propose something like:
PUT /api/v1/resource/:id/likes/:userid
DELETE /api/v1/resource/:id/likes/:userid
我们还有一个额外的好处,即用户只能注册一个赞"(他们可以重复多次赞",而且由于 PUT
是幂等的,因此它具有无论执行多少次,结果都相同).DELETE
也是幂等的,因此如果Unlike"操作由于某种原因重复多次,那么系统将保持一致状态.当然你可以用这种方式实现POST
,但是如果我们使用PUT
和DELETE
,我们可以看到与这些动词相关的规则似乎非常适合我们的用例.
We also have the added benefit that a user can only register one 'Like' (they can repeat that 'Like' as many times as they like, and since the PUT
is idempotent it has the same result no matter how many times it's performed). DELETE
is also idempotent, so if an 'Unlike' operation is repeated many times for some reason then the system remains in a consistent state. Of course you can implement POST
in this way, but if we use PUT
and DELETE
we can see that the rules associated with these verbs seem to fit our use-case really well.
我还可以想象另一个有用的请求:
I can also imagine another useful request:
GET /api/v1/resource/:id/likes/:userid
这将返回赞"的详细信息,例如制作日期或序号(即这是第 50 个赞!").
That would return details of a 'Like', such as the date it was made or the ordinal (i.e. 'This was the 50th like!').
这篇关于检查/取消选中喜欢/不喜欢喜欢/不喜欢资源的 REST 方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!