我的回答:/users.json
。HTTP 针对大粒度超媒体传输进行了优化;缓存是其中很重要的一部分,上面给出的 URI 方案都不是对缓存非常友好的。
例如,Squid 是一种流行的 HTTP 缓存,默认情况下它不会缓存任何具有查询字符串的 URL。此外,许多客户端甚至服务器和中介都以未定义的顺序生成和使用查询字符串参数;即“?a=3&b=5”可以任意改写为“?b=5&a=3”。但是,对于 HTTP 缓存,顺序很重要,即使两个页面具有相同的内容,它们也会被单独缓存。当您添加参数时,此问题会呈指数增长。
您应该设计您的资源(及其表示形式)以通过两种相反但互补的技术来利用缓存:
- 将碎片化和部分表示组合成更大、统一的表示,并
- 沿着缓存边界(往往是事务边界)将大的、统一的表示分成较小的表示,但通过超链接相关。
在您的情况下,步骤 1 意味着将关联和部分组合到“用户”表示中,客户端没有任何选项来配置哪些和多少。这将允许您积极地缓存单个响应表示,而不会由于所有查询字符串选项而使您的(及其)缓存因响应组合爆炸而过载。
第 2 步意味着分离/users.json
成单独的“用户”实体,每个实体都有一个“关联”资源和一个“部件”资源。所以/users/{id}
和/users/{id}/associations
和/users/{id}/parts
。然后,“/users”资源返回一个指向各个“/users/{id}”资源的超链接数组,每个“/users/{id}”表示都包含指向其关联和部分的超链接(该部分更具延展性- -将关联和部分直接嵌入到用户资源中可能更适合您的应用程序。这将允许您积极缓存每个“需求”资源的响应,而无需缓存整个数据库。
Then your users will scream "but that's 10 times the network traffic!" To which you calmly respond, "no, that's 1/10th the network traffic, because 9 times out of 10 the requested resources are already sitting in your client-side (browser) cache (and when they're not, it's 1/10th the server's computational resources since they're sitting in a server-side cache, and when they're not there either, we avoid stampeding with a smart cache on the server)."
Of course, if the /users
resource is something a million new visitors hit every day, then your optimization path might be different. But it doesn't seem so based on your example URI schemes.