【问题标题】:Proper route pattern for RESTful collections with additional resources具有附加资源的 RESTful 集合的正确路由模式
【发布时间】:2016-09-19 15:58:57
【问题描述】:

我已经做了很多 RESTful API(公开和使用 3rd 方),我看到以下两种模式出现在这里和那里。每个都有优点和缺点,在我看来都不是“干净”的。

所以情况是:您有一个集合资源(例如“资产”)并且您想在集合中公开一些额外的资源(例如集合本身的子资源,而不是资产,例如聚合视图端点或某些命令) .

我看到的两种模式是:

  1. 人们创建一个 RESTful 集合资源,例如 /assets/${asset-id},并公开他们需要的所有其他内容,例如 GET /assets/ownedGET /assets/summaryPOST /assets/recheck-inventory。这看起来简洁明了,但在 ${asset-id} 和子资源 URL 的名词之间引入了冲突(例如,asset12345summary 在 URL 中的相同位置)。

  2. 其他人做/assets/items/${asset-id} 并暴露GET /assets/ownedGET /assets/summary 等所有内容。从路由的角度来看,这更清晰,更有前瞻性,但在路由中添加了一个额外的名词,这会在人们尝试使用 POST /assets 时导致混淆。

到目前为止,我所经历的“最佳实践”指南完全避免了这个问题。我也明白 REST 是一种约定而不是标准,并且有一个通用的“它取决于”答案。不过,我觉得这里必须有一个通用的建议。

因此问题是:你会使用哪两个?

更新:为了澄清,让我们假设:

  • /assets/owned 包含不同类型的实体,而不是资产,因此它不是查询,您可以在其中获取/发布/删除项目。
  • /assets/summary 是一个汇总文档(例如带有数量的报告)
  • /assets/recheck-inventory 是一个命令(即仅 POST)

此外,我们希望坚持 REST 原则:

  • 路由的路径应唯一标识一个实体及其状态。
  • 查询参数会改变返回的元素,但不会改变负载格式。
  • 标头用于协议级信息,不会更改服务逻辑(即表示、安全、缓存等)

【问题讨论】:

  • 关于最后一点:URL 中的路径可以是任何东西,包括没有层次结构的 GUID,并且界面仍然可以是 RESTful。

标签: rest collections routes hateoas


【解决方案1】:

我也不喜欢这些方法,但请注意,REST 不会限制如何设计 URI 结构,因此您可以做任何您认为正确的事情。显然,这些 Web 服务的开发人员认为这种方法是正确的。

我会用你的 URI 做类似下面的事情,因为我更喜欢平面 URI。

/assets/items/${asset-id}
  -> /assets/${asset-id}
/assets/owned
  -> /assets/?owned
  -> /assets/?owned=true
/assets/summary
  -> /assets-summary
  -> /assets/ + "Prefer: return=minimal"

您可以找到有关prefer header here 的更多信息,但请注意,如果您希望它成为二级缓存键,则需要通过vary header 注册它。

【讨论】:

  • 感谢您的指点。老实说,到目前为止,我从未遇到过 Prefer/Vary 的用法。但是已经看到了一些 X-WHATEVER-GIVE-ME-WHAT-I-WANT 自定义标题 ;-)
  • 总的来说,我同意扁平结构更简单,而且往往更好。我试图弄清楚如何处理 nested 资源模式,而不是完全避免它们;-) 这是我不将此标记为答案的唯一原因。
  • @Borv 这并不难,它是一个简单的 map reduce。例如,/assets/ 是整个列表,/assets/x/ 是包含较少项目的简化列表。 x 是一个过滤器,可以是owned$id 等...我会将summary 放入查询而不是放入路径部分/assets/?summary=1,因为它不会减少原始集合,它只返回整个 /assets/ 集合的不同表示。如果$id 也可以是"owned",那么您需要在$id 之前添加前缀,例如:/assets/id:$id//assets/id/$id/,或者您可以使用owned 作为通配符。
  • 这是一个有趣的建议,我从没想过 REST 的 map-reduce 语义。通常人们认为相反(路径代表结构,查询代表选择或过滤)。你碰巧知道任何文章或样品吗?标识符也很好。实际上,像在 odata (/assets/(12345)) 中一样将括号放在它们周围有助于避免冲突。
  • @Borv 据我所知,URI 和 IRI 标准将路径描述为分层部分,将查询描述为标识符的非分层部分,您将 map reduce 建模为主要的层次结构组和简化的子组。我不知道是否有关于此的文章,这对我来说很明显,所以我很确定有。 Google 是您的朋友...
猜你喜欢
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 2011-10-09
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多