我在我的 REST 服务器中设置了一个很好的资源层次结构,但是我有一个用例让我感到困惑。
我们有一个相当典型的项目/组设置,并且引用项目中的所有组很容易。但有时,我希望所有组具有给定状态(跨所有项目)。这在标准子资源层次结构中显然是不可能的。
我看到的唯一干净的解决方案是将组同时作为资源和子资源(因为它们可以使用唯一键寻址)。我之前考虑过“别名”资源的概念(以两种不同的方式处理同一资源),但我不确定表达这一点的最佳方式。
我在我的 REST 服务器中设置了一个很好的资源层次结构,但是我有一个用例让我感到困惑。
我们有一个相当典型的项目/组设置,并且引用项目中的所有组很容易。但有时,我希望所有组具有给定状态(跨所有项目)。这在标准子资源层次结构中显然是不可能的。
我看到的唯一干净的解决方案是将组同时作为资源和子资源(因为它们可以使用唯一键寻址)。我之前考虑过“别名”资源的概念(以两种不同的方式处理同一资源),但我不确定表达这一点的最佳方式。
如果您希望您的应用程序与规模无关,最好将您的基本资源视为唯一标识的实体(请参阅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/