【问题标题】:RESTful API subresource patternRESTful API 子资源模式
【发布时间】:2015-07-17 21:03:43
【问题描述】:

在设计 RESTful API 时,以下调用为我们提供了用户 123 的基本信息(名字、姓氏等):

/api/users/123

我们有很多关于用户的信息,因此我们会进行额外的调用以获取用户的子资源,例如他们的购物车:

/api/users/123/cart

对于管理页面,我们希望查看所有用户的所有购物车信息。一张大表,列出了每个用户以及有关他们购物车的一些详细信息。显然,我们不想为每个用户(大量请求)进行单独的 API 调用。使用 RESTful API 模式如何做到这一点?

/api/carts/users 浮现在脑海中,但理论上你有两种方法可以通过 /api/carts/users/123 获取特定用户的购物车。

【问题讨论】:

  • 你能定义两个api吗,一个给/api/users/{userId}这样的用户,另一个给/api/carts/{cartId}这样的购物车?
  • 购物车对象包含属性 userId。对于管理页面,您可以使用类似 '/api/carts?page=1' 的内容来获取前 X 个购物车。然后使用 userId(从购物车对象中提取)发送另一个请求,例如 'api/users?id = id1, id2, id3...` 以获取用户信息。
  • 购物车有点误导。就我而言,这不是一个实体。它更多的是对用户购物行为的统计和分析的总结。所以它并没有真正的 ID,而只是在 API 的服务方法中创建的一堆计算的统计信息和摘要信息。我调用 /api/users/123/cart 来获取用户关于他们购物的统计信息。我也可以通过调用 /api/org/111/cart 来获取有关企业的“购物车”(统计信息/摘要信息)。因此,如果我想要所有用户的购物车(或统计信息)列表,我想知道 /api/carts/users 是否是正确的方法。似乎有些错误,但不确定。

标签: rest restful-url restful-architecture


【解决方案1】:

这通常通过向 REST 服务器添加 deref 功能来解决。假设您的用户的响应如下所示:

{
  ...
  cartId: "12345",
  ...
}

您可以通过传入查询字符串“&deref=cart”来添加一个简单的取消引用(或者您可以设置您的语法。)

这仍然存在按用户发出请求的问题。我认为通常有两种方法可以做到这一点。第一种是使用 multiget 类型的资源(参见 [1] 中的示例)。这种方法的问题是您必须知道所有的 ID 并自己处理分页。第二个(我认为更好)是为您的用户资源实现索引端点。索引允许您查询资源(通常通过查询字符串,例如 firstName=X 或您想要排序的任何其他内容。)然后您应该实现基本分页,这样您就不会传递大量数据。有很多分页示例,但最简单的方法是指定一个数字 (count=20) 一个起始标记 (since=X) 和一个排序顺序 (sort=-createdAt)。

这些实现允许您通过在索引端点上迭代来询问所有用户及其购物车。作为分页 [2] 的起点,您可能会发现这很有帮助。

[1] - How to construct a REST API that takes an array of id's for the resources

[2] - Pagination in a REST web application

【讨论】:

  • 在我的情况下,购物车并不是一个实体。它更多的是对用户购物行为的统计和分析的总结。所以它并没有真正的 ID,而只是在 API 的服务方法中创建的一堆计算的统计信息和摘要信息。我同意你关于使用索引/查询参数进行分页。那么您是否建议使用 /api/carts/users?count=20&first=0 之类的 URL 路由?
  • @Jeremy 很难说。通过诸如此类的端点计算的实体使事情变得更难做。如果您从逻辑上考虑您在做什么,那么您正在获取一堆用户及其购物车信息。您的建议是获取购物车并可能将这些购物车上的用户编入索引。听起来很混乱。我认为 user 是这里的对象,即使计算了购物车,将其视为对象上的字段(例如,可通过查询参数访问)也值得考虑清楚。
【解决方案2】:

出于某种原因,我假设有 2 个指向同一资源的 URI 是一件坏事。在我的情况下 /api/users/123/cart 和 /api/carts/users/123 将返回相同的数据。通过更多的研究,我从无数来源了解到,如果对最终用户有意义的话,对同一资源有多个 URI 是可以接受的

在我的情况下,我可能不会公开 /api/carts/users/123,但我计划使用带有一些查询参数的 /api/carts/users 来返回系统中的购物车子集。同样,我将使用 /api/carts/orgs 来搜索组织购物车。

REST API Tutorial 是我发现的一个非常好的站点,其中包含示例和清晰的解释。我希望这有助于其他人规划他们的 API URI。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多