【问题标题】:REST API design - querying mail data - which poison to choose? [closed]REST API 设计 - 查询邮件数据 - 选择哪种毒药? [关闭]
【发布时间】:2012-04-25 14:19:22
【问题描述】:

我们目前正在设计一个内部 REST api。我们有以下用例:

  1. 用户 (109) 想要阅读他发送给另一个用户 (110) 的消息
  2. 阅读用户 (109) 通过他在身份验证后(执行 GET 请求时)收到的令牌凭据为应用所知
  3. 我们假设在这个例子中用户 109 是发送者,110 是接收者

从用户的角度总结“给我我(109)发给110的邮件”

我们想到了以下 URI,但我们无法决定采用哪一个:

a) GET http://localhost:9099/api/mails/109?receiverUserId=110
b) GET http://localhost:9099/api/mails?senderUserId=109&receiverUserId=110
c) GET http://localhost:9099/api/mails?receiverUserId=110
d) GET http://localhost:9099/api/mails/me/to/110 (when logged in as 109 via token credentials we know that "me" is 109)
f) GET http://localhost:9099/api/mails/109/to/110 (explicit request, e.g. for admins … has to be guarded against illegal access)

所有链接都是“上下文敏感的”,将链接之一发送到接收器 (110) 将产生执行 GET 请求的不同结果。

我想知道您对使用哪个网址的看法。

非常感谢任何帮助。

干杯 马塞尔

【问题讨论】:

  • 观察一下:(b) 和 (d) 是相同的。
  • 我投票给 c。众所周知,我没有看到指出阅读用户的意义。 (不过缓存除外)

标签: api http url rest


【解决方案1】:

对不同客户端的不同响应,对于相同的 URL 是可以的。

StackExchange 做到了:

GET /me/comments/{toid}

记录在here

Twitter 也这样做:

GET /statuses/home_timeline

记录在here

这两个 URL 都基于身份验证推断登录用户。是的,如果用户共享缓存,它会破坏缓存,但是 IMO,这没关系。这是否打破了 REST 的“资源识别”约束可能值得商榷。 this 问题的答案以及随后的评论向我展示了它为什么值得商榷。

事实上,在这些选项中,您确实提到了不是“上下文敏感”的 URL:

GET /api/mails?senderUserId=109&receiverUserId=110

这个总是会返回从 109 到 110 的消息。但是,当一个客户端在查看“已发送”消息时希望看到此结果时,另一个客户端希望在查看“已接收”消息时看到此结果。有点奇怪吧?另外,在服务器上,您必须检查经过身份验证的用户是 109|110,否则抛出 401 UNAUTHORIZED

我会选择类似的东西:

GET /mail/sent

返回所有发送的邮件。并且:

GET /mail/sent?to=110 (like applying a 'filter' to /mail/sent)
OR
GET /mail/sent/110 (clean URL)

返回发送到 110 的邮件。

【讨论】:

  • 感谢您的回答。我想我们会选择提供的链接之一。
【解决方案2】:

“上下文相关”链接对于 REST API 来说是个坏主意(特别是,这会阻碍缓存)。如果您只想使用 HTTP,这没关系。

所以我建议使用不依赖于当前用户的 URL,并根据您的规则限制对它们的访问。

【讨论】:

    【解决方案3】:

    在我看来,你需要 2 层:

    一个是内部层,它不需要用户身份验证,它只能从内部组件访问。它包括像

    这样的 API

    GET http://localhost:9099/api/mails?senderUserId=109&receiverUserId=110

    这一层的优点是可测试性、可重用性和可缓存性。

    另一层是外部层,它需要用户认证并且可以从外部客户端访问。它包括像

    这样的 API

    GET http://localhost:9099/api/mails?receiverUserId=110

    客户端必须登录才能获取令牌凭据,然后服务器可以从该令牌中获取用户信息,并将外部 API 调用映射到内部 API 调用。

    你可能有不同的认证方式,但内部层不会改变,你只需要将不同的外部层映射到内部层。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      • 2019-07-06
      • 1970-01-01
      • 2012-04-17
      • 2013-08-15
      • 1970-01-01
      • 2018-02-26
      相关资源
      最近更新 更多