我在REST服务器中设置了良好的资源层次结构,但是我有一个令我困惑的用例。
我们有一个相当典型的项目/组设置,并且引用项目中的所有组都很容易。但有时,我希望所有具有给定状态的组(跨所有项目)。在标准的子资源层次结构中,这显然是不可能的。
我看到的唯一干净的解决方案是同时将组作为资源和子资源(因为它们可以使用唯一键进行寻址)。我之前已经考虑过这种“混叠”资源的概念(以两种不同的方式处理相同的资源),但我不确定表达它的最佳方式。
答案 0 :(得分:1)
如果您希望您的应用程序与规模无关,最好将您的基本资源视为唯一标识的实体(请参阅Helland),但允许公开它们的索引。最常见的索引形式是包含其项目的集合,使用HTTP URI的分层特性:
GET /groups/
200 OK
{"entities": [
"/groups/1/",
...
"/groups/212/",
],
}
我们可能称之为“主要指数”。但还有许多其他可能性:
GET /projects/foo/groups/
200 OK
{"entities": [
"/groups/7/",
"/groups/182/",
],
}
GET /groups/by_status/ACTIVE/
200 OK
{"entities": [
"/groups/13/",
"/groups/64/",
],
}
请注意这些备用索引,因为它们往往与现实不同步,尤其是当你将多个服务器和缓存放入混合时(阅读Helland的论文)。这就是为什么上面的示例输出由链接组成,而不是原子实体本身的副本。出于同样的原因,您不希望有两个URI来标识相同的原子实体。当多个客户端获得相同数据的多个副本时,这将导致过时数据和丢失更新。
如果一个实体可以通过两个不同的标识符进行真正识别,例如数字ID和唯一名称,那么选择一个是规范的,让另一个重定向到它:
GET /groups/by_name/bar/
303 See Other
Location: /groups/44/