1

所以我读了很多关于 RESTfull 设计的书——特别是处理资源。

用户帖子评论的典型例子为例,关系如下:

用户 ---(hasMany)---> 发布 ---(hasMany)---> 评论

最初可能会考虑公开以下内容:

GET /users               GET /posts               GET /comments 
POST /users              POST /posts              POST /comments 
GET /users/id            GET /posts/id            GET /comments/id
PUT /users/id            PUT /posts/id            PUT /comments/id
DELETE /users/id         DELETE /posts/id         DELETE /comments/id

但是,假设我想要某个特定用户发表的某个帖子的所有评论。我需要做类似的事情:

GET /users/id
   > someUser
   > var postIds = someUser.posts()
GET /posts?id=<postIds[0]>&id=<postIds[1]>&...
   > somePosts
   >  **application user inspects posts to see which one they care about**
   > var postOfInterest = somePosts[x]; 
   > var postId = postOfInterest.id;
GET /comments?id=postId
   > someComments (finally)

假设我只关心它所有者上下文中的帖子评论。假设不同的资源结构可能(也可能不是?)更自然:

GET /users
POST /users  
GET /users/id   
PUT /users/id
DELETE /users/id

GET /users/id/posts
POST /users/id/posts
GET /users/id/posts/id
PUT /users/id/posts/id
DELETE /users/id/posts/id

GET /users/id/posts/id/comments
POST /users/id/posts/id/comments
GET /users/id/posts/id/comments/id
GET /users/id/posts/id/comments/id
GET /users/id/posts/id/comments/id

对我来说,这可能是对资源的更好表示。然后我需要的是:

GET /users/id/posts
   > somePosts
   > **application user inspects posts to see which one they care about**
   > var postOfInterest = somePosts[x];
   > var postId = postOfInterest.id;
GET /users/id/posts/postId/comments
   > someComments

与以前的方法相比,这似乎更像是在文件系统中导航——但我根本不知道它是否是 RESTfull(也许这是 REST 试图摆脱的),因为为了访问Comments资源,我需要知道它属于哪个用户和哪个帖子。但前者需要 3 个请求,而后者只需要 2 个。

想法?

4

2 回答 2

1

相当多的好 REST 是意见,但我会说你的第二种方法通常更“RESTful”。

基本上,您确实需要 REST API 和文件系统中的层次结构,例如导航而不是查询参数。如果您遵循 HATEOS 之类的 API,则尤其如此,因为有人可以浏览您的 API。

于 2013-10-01T18:28:39.887 回答
1

在您的第二个示例中,两者兼有 GET /users/id很重要,GET /users/id/posts因此当请求用户信息时,它也不包括所有帖子(或他们的 ID)。第二个请求也将返回他们的帖子。用户通常在论坛中有数千个帖子。

缺点是 api 用户总是必须知道它想要获得评论的帖子的作者。他基本上会向您的服务器发出“给我该用户并给我他/她的帖子”请求,这意味着您的服务器将为该用户进行查询,然后选择他的帖子。相反,您的用户和您的服务器有单独的请求更方便 - “给我那个用户”,“给我那个帖子”和“给我那个评论”。这意味着您必须单独存储用户、帖子和评论,并为每个帖子/评论存储其作者的 id,以便您可以按作者选择帖子/评论(“给我这个用​​户的帖子”,或者简单地说“给我这个帖子”)

我个人会使用这种请求变体

GET user
GET post
GET comment
...

对于每个请求,我都会实现一个where子句,该子句将为我的 api 用户提供更多选项来进行特定选择。例如GET posts where userId='myID'. 它可以使用url 查询参数(如http://myapi.mydomain.com/post?userId=user1标题或标题内)来实现。它将返回该用户的帖子列表。您还可以为where帖子的 ID 设置子句 -http://myapi.mydomain.com/post?id=123这将只返回此帖子。请注意,对于第一种情况 - 当您获取帖子列表时 - 您只能返回帖子的某种简短信息(如 id、作者、摘要......),并且需要额外请求才能post?id=id获得完整的帖子内容。

拥有这个实现会给你至少两个好处:

  • api 的用户只需要知道一个 id 即可获取一些信息 - postID 获取帖子的内容/评论,userId 获取该用户的所有帖子/评论
  • 选择是在服务器上完成的,因此通过网络传输的数据更少,这意味着更快的响应(如果最终用户使用移动计划或其他方式,则可能会降低成本)

在我看来,此实现为您提供松散耦合的对象(用户、帖子、评论)和更灵活的查询

于 2013-10-02T09:10:53.933 回答