rest - 带有身份验证的 RESTful API URL 设计
问题描述
我的数据模型是这样的:
User: id, email, hashed_password
Item: id, name, color
UserItem: user_id, item_id, rating
我想编写一个 RESTful API 来获取这些资源。身份验证是通过 OAuth 2 提供的,带有 JWT 令牌(包含记录的用户 ID)。
第一种方法
端点
URL 结构的第一个想法是(我在仍然没有身份验证时选择的那个):
/items/{item_id}
/users/{user_id}
/users/{user_id}/items/{item_id}
在这种情况下,ID 为 1 的用户可以使用:
GET /users/1
获取自己的信息;GET /users/1/items
获得自己的物品(带有评级);GET /items
获取他们可以添加到收藏中的所有项目。
分析
我认为这个解决方案很清楚,但也不优雅。
好的:
- 您可以轻松获取其他用户信息(如果他们可用);
- 端点和数据模型之间的一对一关系。
坏的:
- 较长的网址;
- 存在冗余(为什么
GET /users/1/items
在令牌中您已经拥有关于 id 1 的信息?)。
第二种方法
端点
鉴于您可以从令牌中提取用户 ID,结构也可以更简单:
/items/{item_id}
/users/{user_id}
在这种情况下,ID 为 1 的用户可以使用:
GET /users/me
获取自己的信息;GET /items?class=owned
获得自己的物品(带有评级);GET /items?class=all
获取他们可以添加到收藏中的所有项目。
分析
这个解决方案有点混乱,但可能更优雅。
好的:
- 较短的网址;
- 减少冗余(
GET /items
获取自己的物品)。
坏的:
- 仅表示模型 UserItem(即使在这种情况下,获得没有评级的项目可能几乎毫无意义,如果用户尚未添加它,则可以将其设置为 null);
- 获取其他用户的项目并不简单(可能是
GET /items?user=3
?)。
结论
老实说,我不知道在这种情况下最好的做法是什么。我觉得这两个都有点不对劲。也许有一种我没有看到的混合方法?
您将如何组织这样的模型?
解决方案
您可以查看 HAL 之类的格式。HAL 为您提供了一种描述特定资源(项目)的方法,并允许您创建指向这些资源的多个集合。
这意味着单个项目可以托管在/items/xyz
,但项目可以同时是/user/a/items
和/items
集合的一部分。
我在一个超媒体客户端上做了很多工作:https ://github.com/badgateway/ketting 。虽然这不仅仅是一个广告,还有其他选择,但我们可能会非常适合您的 API 设计方法。
但无论您使用哪种客户端,这样的系统都可以避免通过多个端点检索相同项目的问题。单个项目具有规范的 url,如果系统设计良好,您只需检索一次项目。
集合只是指向属于该集合的资源(项目)的链接列表。它们指向项目,但不“包含”,就像常规超链接一样。
推荐阅读
- json - ADF V2 - 使用动态内容和变量的 Web POST 方法
- javascript - 如何在eval中使用动态字符串
- java - 如何在 JsonRPC 参数的函数中切换表?
- linux - 在 GDB gcore 创建的核心转储中包含共享库的只读段
- java - 引起:java.lang.ClassNotFoundException:com.jfoenix.controls.JFXButton
- javascript - Number.Nan 在这个函数中是如何工作的?
- elasticsearch - Elasticsearch 存储桶聚合返回错误的 doc_count
- ios - UICollectionView 不在 UITableViewCell 内滚动
- python - 字符串中已有“{}”时的Python字符串格式化
- sql-server - 尝试在 LINKED SERVER 上更新表时出现问题