我正在设计REST API,最近我考虑了如何为动态内容进行大部分缓存(在this topic的响应之后),同时尊重HTTP的原则(以及REST) )。
显然,规范解决方案(至少在我的理解中)是使用etags,但这不会以任何方式减少请求数量,只是大小。
我在考虑在URL中嵌入一个版本(它将根据实际内容生成服务器 - 无论是序列号还是一些哈希值)。我将解释该方案和用户场景以及我认为它将如何帮助,然后提出我的问题。
设置
GET /entity/{id}/
将临时重定向返回到/entity/{id}/{current_version}
和无缓存标头。
GET /entity/{latest_version}/
永远返回带缓存的OK响应。
GET /entity/{old_version}/
返回410 Gone(我不想实际保留旧版本)。
GET / entity /?[查询]
是一些搜索,返回指向当前版本结果实体的链接列表。没有缓存。
使用方案以及我认为它会有所帮助
用户应用程序(AJAX)将始终以某种查询开始,然后它必须提取实体的描述。由于预计单个客户端结果集的更改不会非常动态,因此使用上述方案并且客户端每次都从查询中提取新结果似乎是个好主意,但是如果大多数实体自上次访问后没有更改,它们已经在浏览器中缓存了。如果这个假设成立,这将导致请求数量和总大小显着减少。
使用etags会导致更简单的URI方案,但可能会更加复杂和繁重的服务器端实现。
备注和问题
1
我知道有人会建议/entity/{id}/
应该是一个返回列表版本的集合,但版本实际上并不存储,有用或不需要。它更像是最新的同义词。我的问题是,除了一般原则之外,如果有人看到任何问题。这是受保护的API,在这种情况下我不关心SEO,它对客户端是透明的。实际上,由于API将或多或少地具有超链接性,因此不希望实际上直接调用/ entity / {id} /,而是使用返回的结果。例如,它可以用于无上下文链接。
2 我对旧版本的410 Gone有些怀疑。一方面,此版本不再可用,客户端无论如何都不应该访问它。另一方面,如果客户端毕竟要求它(无论出于何种原因),将永久重定向返回到/ entity / {id} /(可能更好地临时重定向到当前版本)可能是有意义的。
第3 说到重定向。 301是固定永久重定向,但302是临时的最佳选择吗?最重要的是浏览器支持(它将是AJAX)。
4 当然,主要问题是使用URL而不是etags进行缓存(希望在浏览器缓存上)。如果有人在高负荷下有实际经验(相对于服务器功能,咳嗽),我将非常感谢分享它。
附加说明
经过一些研究后,版本化资源存在问题,而且是链接资源的更新传播。有两种选择:
链接特定版本的资源。这意味着服务器端逻辑将是繁重且繁琐的,因为必须通过反向链接传播链接资源的更新;
链接/ latest / version。这意味着即使资源和链接的资源具体版本都在本地缓存,客户端(浏览器)也必须向/ latest /发出请求以便检查'最新版本的链接资源。当然这是一个小请求(仅重定向),如果资源没有更改位置已经缓存。一个问题可能是经常从这样的链接中提取资源(与查询结果相反的是特定版本)。另一个(更糟糕的)问题是,资源的旧版本实际上是链接另一个版本的最新版本 - 它可能是数据不一致(即某人编辑了文档并且还更改了链接附件 - 客户端将具有旧版本的文档和新版本附件)。
两种选择都不令人满意。在这种情况下,动态数据的轻松缓存仅适用于“叶子”。级别资源 - 没有链接到任何其他资源的资源,胸部只有直接的属性值。
最后的笔记
经过研究和讨论,版本化资源并不是一般架构最明智的想法。经过测量并给予机会,可以在标准API中对某些内容进行改造,以便简单地进行操作。资源。我会接受Roysvork的评论('我认为这很难的原因是它不是一个非常好的主意。')作为解决方案,如果它是一个单独的答案: )