2012-07-06 50 views
0

我在我的REST服务器中建立了一个很好的资源层次结构,但是我有一个使我感到困惑的用例。如何跨多个父资源引用子资源?

我们有一个相当典型的项目/组设置,并引用所有组的一个项目是很容易的。不过,有时候,我希望所有具有特定状态的群体(跨所有项目)。这在标准的子资源层次结构中显然是不可能的。

唯一干净的解决方案我看到的是在同一时间有团体作为一种资源和子资源(因为它们是可寻址的一个独特的密钥)。我以前曾经考虑过这种“别名”资源的概念(以两种不同的方式处理同一资源),但我不确定表达这一点的最佳方式。

回答

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/", 
     ], 
    } 

谨慎使用这些替代指数,但是,因为他们往往不同步的现实,尤其是当你把多个服务器和缓存到混合(读埃兰的纸) 。这就是为什么上面的示例输出由链接组成,而不是原子实体本身的副本。出于同样的原因,你不希望有两个标识相同原子实体的URI。这将导致陈旧的数据和丢失的更新,因为多个客户端获取相同数据的多个副本。

如果一个实体是由两个不同的标识符,真正的身份,如数字ID和一个唯一的名称,然后选择一个要规范,并有其他重定向到它:

GET /groups/by_name/bar/ 
    303 See Other 
    Location: /groups/44/ 
+0

感谢您的参考,我会确保彻底阅读它。为什么两个URL会强制陈旧的数据,假设他们在同一台机器上?他们最终会针对相同的缓存调用相同的加载方法。当然,你需要在多台机器上保持多个缓存同步。 – JasonB 2012-07-09 17:43:35

+1

我的意思是HTTP缓存,它位于服务器和客户端之间,而不是服务器后面。例如,如果客户端获取资源'/ groups/44'和'/ groups/by_name/bar',并将它们粘贴在本地HTTP缓存中,则向'/ groups/44'发布PUT,它只会失效'/ groups/44'的缓存,但是'/ groups/by_name/bar'仍然会包含旧的数据。 – fumanchu 2012-07-09 18:49:36

+0

但是,如果您重定向,如上所示,那么客户端将只有一个副本缓存,并且PUT会使其正确无效。 – fumanchu 2012-07-09 19:41:58