【问题标题】:RESTful API design: best way to CRUD lightweight connections?RESTful API 设计:CRUD 轻量级连接的最佳方式?
【发布时间】:2012-12-01 08:45:55
【问题描述】:

(请原谅问题标题;这个问题很难概括。)

在 Facebook 上,你 like 的东西。在 Twitter 上,你 follow 人。在 GitHub 上,您还可以使用 follow people 和 star repos 和 gists。

所有这些情况都非常相似:这些连接是轻量级的,而不是真正的“资源”本身。例如。这三个 API 都没有公开此类连接的公共 ID。

这就提出了一个问题:公开用于创建/查询/删除这些连接的 API 的“最佳”(就 REST 而言)方式是什么?


Facebook 确实 [1]:

  • GET /:id/likes 查询对象的喜欢(更准确地说,是喜欢该对象的用户)

  • POST /:id/likes 点赞(代表经过身份验证的用户;不需要请求正文)

  • DELETE /:id/likes 不同于某些东西(代表经过身份验证的用户)

查询和创建是有意义的,但 DELETE 有点“unRESTful”,因为您实际上并没有删除 /:id/likes 资源(喜欢该对象的用户数组)。

这种差异在另一种情况下表现出来 [2]:

  • GET /me/likes/:id查询你是否喜欢某样东西

因此查询您的连接是查询与创建或删除完全不同的资源。


GitHub 倾向于 /me/likes/:id 风格来关注用户并由 repos [3] 主演:

(请注意,GitHub 的 /user 代表经过身份验证的用户,如 Facebook 的 /me。)

  • GET /user/starred/:owner/:repo 用于查询您是否已为 repo 加注星标(返回 204 或 404,两种方式都没有正文)

  • PUT /user/starred/:owner/:repo 为 repo 加注星标(请求中不需要正文)

  • DELETE /user/starred/:owner/:repo 取消标记仓库

这更加一致,但不幸的是,这将单个“星”与组分开:

  • GET /repos/:owner/:repo/stargazers 查询已加注星标的用户

GitHub,有趣的是,使用了不同的风格来为 gists [4]:

  • GET /gists/:id/star 用于查询您是否已加注星标

  • PUT /gists/:id/star 主演一个要点

  • DELETE /gists/:id/star 取消标注要点

这将使用 gist 资源(如 Facebook)而不是用户资源来保持星标操作。

GitHub 不会公开 gists' 观星者,但大概是例如:

  • GET /gists/:id/stargazers 查询已加星标的用户

虽然“stargazers”确实是与“star”不同的资源/名称,但名称相似且明显相关,并且它们都位于同一资源上。

我能想到的唯一缺点是命名资源。 star 之类的方法有效,但 followlike 之类的操作更棘手。


(懒得以 Twitter API 为例,因为它几乎不是 RESTful。)

显然没有完美的 RESTful API 可用于创建/查询/删除不合适的资源,但是否还有其他我没有看到的优点/缺点,或者需要考虑其他样式?

谢谢!

【问题讨论】:

  • 您的 url 结构如何查找 3 个状态,喜欢、不喜欢和撤消投票(喜欢或不喜欢)

标签: web-services api facebook-graph-api rest github-api


【解决方案1】:

我喜欢/me/likes/:id 风格的一件事是,喜欢的人确实感觉像是个人的、可寻址的资源——例如他们有单独的 ID(恰好和我喜欢的东西一样)。

GitHub 的 repo API 很好地使用它来创建/查询/删除到 repos 的“星形”连接,但是对于给定的获取 所有“星形”连接存在差异回购。

也许可以通过更改处理这些连接的方式来解决差异:不要仅仅依赖对象 ID,还可以使用(经过身份验证的)用户 ID。例如:

  • GET /:owner/:repo/stargazers 查询所有已加注星标的用户

  • GET /:owner/:repo/stargazers/:id 查询用户 :id 是否已为 repo 加注星标 -- 这可以通过指定 me 来成为经过身份验证的用户!

  • PUT /:owner/:repo/stargazers/me 为 repo 加注星标 -- 这仅适用于经过身份验证的用户

  • DELETE /:owner/:repo/stargazers/me 取消标记回购 -- 同上

现在所有资源/动作都在一起了,动作一致,命名也很容易。

编辑:这种方法的另一个好处是,您可以轻松高效地查询其他用户是否也喜欢/关注/加注对象。

编辑:但缺点是资源在技术上不再正确——GET .../stargazers 返回一个用户列表,但GET .../stargazers/:id 返回一个连接,而不是用户。哦,好吧?

[再次编辑以支持将me 也作为:id 传递。]

【讨论】:

    【解决方案2】:

    我觉得

    DELETE /:id/likes to different things(代表经过身份验证的用户)

    是有道理的,因为 like 会有一个被喜欢的对象的 id 和你的用户 id 的复合键,所以当你的身份验证登录已经告诉你是谁,而你甚至没有权限时,指定一个 id 只是多余的还是删除其他用户的赞。

    明确指定(如 Aseem Kishore 所建议的那样)

    删除 /:id/likes/me

    ...可能会更清楚一点。

    【讨论】:

      猜你喜欢
      • 2014-10-19
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多