【问题标题】:RESTful services naming: GET the details of a list of productsRESTful 服务命名:获取产品列表的详细信息
【发布时间】:2015-02-06 11:05:40
【问题描述】:

我试图了解哪种应该是正确的 REST 方法来命名一些电子商务风格的端点。

如果我没记错的话,获取产品列表和每个产品的详细信息最终会得到两个 GET 端点

A) 获取/产品

B) 获取 /products/id

(我故意跳过了分页问题)

如果我正在查看销售特定产品的商店列表,我可以指定和端点

C) 获取 /products/id/shops

我很难理解如果我需要为商店研究指定多个产品会发生什么。

是否可以将上述端点扩展为采用多个参数,或者不鼓励这样做? 换句话说,我应该研究类似的东西

1) 获取 /products/id1,id2,id3/shops
2) 获取 /products/id1/shops [id2,id3]

或者说是全新的

3) 获取 /shops [id1,id2,id3]

?

备注

  1. Unanswered question in SO 似乎强调这是 RESTful 服务中一个不为人知的故事...... :)
  2. My current source of reference
  3. 正如许多 SO 答案中所提到的,例如 here,URI 不会使服务成为 RESTful。

    我同意这一点,所以为了扩展这个概念,我上面的观点是,上面的服务的 实现(如 1)可能是(在我的情况下,对于服务器实现细节) ) 不同于以 C) 的形式轻松组合 3 个端点给出的结果。

    在更一般的意义上,这种组合的实现可以保留在内部。

    因此,是的,URI 不会使服务成为 RESTful,但如果为多个 id 扩展 C) 形式的简洁性和表达性会很好。

编辑 响应 Lutz 在回答中的正确注释,商店可能被视为自己的资源。 如果,我想出了这个不太聪明的例子,子资源本身并不真正存在,例如电影院中两部电影的免费位置

GET /movies/12,14/places

在哪里

GET /places?movies=12,14

显然是可行的,但不是那种 RESTful 恕我直言。

【问题讨论】:

  • 获取产品列表的详细信息不一定需要多次请求。 GET /products 的响应负载不能包含每个产品的所有详细信息,这与 URI 设计无关。这可能存在性能或其他问题,只有熟悉您正在创建的产品的人才能知道,但这是您团队的设计决策,而不是 REST 的约束。

标签: rest restful-url


【解决方案1】:

我同意 Lutz Horn 给出的答案。此外,我不确定您为什么认为在 GET 请求中使用查询字符串“不是那种 RESTful”。

引用O'Reilly's RESTful Web Services, pg 233, 在标题 URI Design 下(强调我的):

使用标点符号分隔同一层级的多条数据。当项目的顺序很重要时使用逗号,就像在纬度和经度中一样:/Earth/37.0,-95.2。当顺序无关紧要时使用分号:/color-blends/red;blue

仅使用查询变量来建议将参数插入算法,或者当其他两种技术失败时。如果两个 URI 仅在查询变量上有所不同,则意味着它们是同一底层算法的不同输入集。

这应该为您确定如何构建路线提供足够的指导。虽然您可以轻松地构造它(使用分号,因为这里的顺序似乎并不重要):

GET /products/id1;id2;id3/shops

你也可以这样写:

GET /shops?productIds=id1,id2,id3

这可能是一种更合理的方法,因为您表示您正在搜索所有携带特定商品的商店,并且搜索是一种以产品 ID 作为输入参数的算法。

对于您的电影示例(如果我理解正确的话),如果您正在寻找正在放映电影(或多部电影)并且有座位的地方(我们的资源):

GET /places?movie=id1,id2,id3&availability=true

您似乎只有额外的搜索参数。如果我误解了您的“子资源可能不存在”的评论,请为我们澄清这一点,以便我们能够正确解决。

【讨论】:

  • 嗨斯科特,我完全错过了你引用的例子。真丢人。您说得对,顺序无关紧要,因此半列似乎是要走的路。
  • 在“不太平静”的部分,我的意思是如果端点在没有上下文的情况下没有意义,那么拥有像 /places 这样的特定端点是否合理。引用同一本书(在移动设备上抱歉没有指向页面)作者强调目的之一是使服务“可发现”,从而使您建议的半列解决方案更加优雅。无论如何,谢谢你的好答案和引用这本书。
  • 如果您希望我就最后一点提供更多详细信息,我非常乐意进一步讨论!
  • 嗯...显然我们在谈论两本不同的书。那我就不客气了! :)
  • 看来是这样。将我的书提及链接到产品页面。
【解决方案2】:

我会将shops 设为单独的资源。

  • GET /shops 列出所有店铺
  • GET /shops/123获取店铺详情123
  • GET /shops?sellsProduct=id1,id2,id3列出所有销售该产品的店铺

/products/id/shops 等 URL 中,商店是产品的子资源。但由于商店可以独立于任何产品而存在,这没有多大意义。

【讨论】:

  • 考虑到子资源可能不存在,请您详细说明一下。如果我们想想一个真实的例子,如果我用电影(在电影院提供)代替产品并在有可用性的情况下购物。因此,按照上面的示例 1 GET/movies/12,14/availability 将为我提供两部电影的联合可用性。结果将与 /availability?movies=12,14 的结果相同,但在这种情况下,它可能会质疑可用性是否独立于电影而存在。
  • 希望不要太复杂:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多