RESTAPI设计:如何处理也可以是子资源的资源

RESTAPI设计:如何处理也可以是子资源的资源,rest,asp.net-web-api,Rest,Asp.net Web Api,我必须将(只读)REST服务置于现有产品数据库之上。最简单的部分是拥有顶级的产品资源,如: /api/products/ 现在,实际上,该服务的调用方需要根据商店和特定流程(如“零售”)的ID获取相关产品。在幕后,这两个值的组合会产生产品的配置子集。这对调用方来说必须是透明的,它不需要知道这些“产品组合” 因此,我考虑像这样设计URI,其中1234是StoreID,retail是流程: /api/stores/1234/retail/products 这里出现的第一个问题是,我是否应该在/a

我必须将(只读)REST服务置于现有产品数据库之上。最简单的部分是拥有顶级的产品资源,如:

/api/products/
现在,实际上,该服务的调用方需要根据商店和特定流程(如“零售”)的ID获取相关产品。在幕后,这两个值的组合会产生产品的配置子集。这对调用方来说必须是透明的,它不需要知道这些“产品组合”

因此,我考虑像这样设计URI,其中1234是StoreID,retail是流程:

/api/stores/1234/retail/products
这里出现的第一个问题是,我是否应该在/api/products/…上将这里的完整产品或URI返回到它们各自的资源中。。。优点是调用方不需要从/api/products中检索每个产品,缺点是这会导致/api/stores/1234/retail/products URI上的缓存问题

更复杂的是,这些产品当然也有价格。同样在这里,一个产品没有一个价格,而是多个价格,除了其他因素外,还取决于StoreID和流程。事实上,价格是产品的直接产物,因此:

/api/products/ABCD/prices
这是一个明显的选择,但同样,由于StoreID和Process与预过滤价格相关,URI如下:

/api/stores/1234/retail/products/ABCD/prices
这样更合适

同时,产品的其他子资源在这个URI下没有意义,比如产品详细信息。这些显然只在/api/products/ABCD/details下才有意义,因为它们不依赖于商店或流程

但我觉得这有点乱。但同时,仅通过使用queryparam筛选器直接在产品资源上解决此问题并没有多大好处,也不会强制调用方同时提供StoreId和process:

/api/products?store=1234&process=retail
/api/products/ABCD/prices?store=1234&process=retail
更重要的是,process或storeid与产品没有任何关系,所以直接在产品上查询它似乎很奇怪。不过,就价格而言,这是有道理的

所以我的问题是:有没有解决这个问题的好方法,我看不到?并且:当产品是子资源时,您会建议返回完整的产品吗?在这样做时,您对处理(HTTP)缓存有何看法

这里出现的第一个问题是我是否应该全额返回 此处的产品或URI在/api/products上指向其各自的资源/ […]缺点是 会在/api/stores/1234/retail/products上引起缓存问题 乌里

我肯定会退回完整的产品——想象一下,如果客户只想显示一个产品名称列表,那么它需要做多少。理想情况下,该端点将被分页(例如,查询字符串可以包括类似于
&pageSize=10&pageNumber=2的内容)

此外,还有各种各样的缓存解决方案,例如,您可以在数据结构服务(如Redis)中缓存所有产品

让事情复杂化的是,这些产品当然也有价格[…] 和子资源的详细信息

查看,这将是链接发挥作用的地方,您可以在产品资源下使用类似的内容:

<link rel = "/linkrels/products/ABCD/prices" 
      uri = "/products/ABCD/prices?store=1234&process=retail"/>

和另一个类似的产品详细信息资源链接

@Roman是对的,REST是可以发现的,客户机应该简单地遵循链接(可能有长/难看的URI),而不是必须记住它们(比如在SOAP中)

这里出现的第一个问题是我是否应该全额返回 此处的产品或URI在/api/products上指向其各自的资源/ […]缺点是 会在/api/stores/1234/retail/products上引起缓存问题 乌里

我肯定会退回完整的产品——想象一下,如果客户只想显示一个产品名称列表,那么它需要做多少。理想情况下,该端点将被分页(例如,查询字符串可以包括类似于
&pageSize=10&pageNumber=2的内容)

此外,还有各种各样的缓存解决方案,例如,您可以在数据结构服务(如Redis)中缓存所有产品

让事情复杂化的是,这些产品当然也有价格[…] 和子资源的详细信息

查看,这将是链接发挥作用的地方,您可以在产品资源下使用类似的内容:

<link rel = "/linkrels/products/ABCD/prices" 
      uri = "/products/ABCD/prices?store=1234&process=retail"/>

和另一个类似的产品详细信息资源链接


@Roman是对的,REST是可以发现的,客户端只需遵循链接(可能有长/难看的URI),而不必记忆它们(例如在SOAP中)。

仅从第一眼看:如果
store
process
产品
资源的参数,我想即使您检索子资源,也可以将它们保留在那里更干净。rescue-
/api/产品的矩阵参数;商店=1234;流程=零售/ABCD/价格
。一般来说,一个好的URI设计不会使一个服务比一个具有更复杂URI的服务更RESTful,因为客户端无论如何都会从服务器响应中了解到它所需要的一切——尽管是在一个真正的RESTful环境中!大多数REST服务不应该调用自己的RESTful,而应该调用HTTP或ASOTOH之上的
API服务
,这是绝对有意义的,但是直接在/API/products URI上公开这一点的一个问题是,存储和处理的组合实际上具有特殊意义,并减少了我选择的数据集。例如,仅传递store ID仍将从所有产品中进行选择,而同时传递这两个ID将仅从配置的子集中进行选择。这就是为什么我认为在查询那个特殊场景时使用一个特殊的URI更有意义,因为存储和进程并没有直接与