计算 REST 的 ETag API
Computing an ETag for a REST API
我们正在构建 REST API,我们将 ETag 用于两种用途:
- 通过允许客户端避免重新加载资源(对我们来说并不重要)来节省带宽
- 解决并发问题(丢失更新问题)
从实际的角度来看,我想知道用什么来计算 ETag。
项目哈希
我们正在使用响应中发送的(json 项目 object 转储的散列。这很好用。检查 PUT 请求很容易:从数据库中提取项目、计算哈希、比较。然而,它使关注点的分离有点“漏洞”:从项目构建响应的层有点与负责 ETag 计算的层交错。此外,附加数据(响应 headers)可能很重要,如果确实如此,发送 304 仅仅因为项目本身没有改变而 headers 确实可能不合适。
响应哈希
另一种方法是在发送之前对响应进行哈希处理。这样做可以使计算部分的 ETag 层更加清晰。但是,在 PUT 请求中,我们不能只从数据库中提取项目来检查 ETag,因为我们没有额外的数据。
第一种方法(计算项目哈希)似乎适用于案例 2 并发问题。第二种方法(计算有效负载哈希,包括元数据,headers)适用于情况 1 节省带宽。
将响应的每一位(包括 headers)放入请求中似乎是正确的,因为那里的每个更改都可能相关并需要客户端刷新其缓存。但是我不知道如何使用这样的 ETag 管理 PUT 或 DELETE 请求的并发。
从实际的角度来看,我们应该使用项目哈希还是响应哈希?我们如何用其中之一来处理这两种情况?
根据您的描述,我认为响应哈希是唯一有意义的。
首先,为了使用条件请求来避免丢失更新问题,验证器 need to be strong.
An origin server MUST use the strong comparison function when
comparing entity-tags for If-Match (Section 2.3.2), since the client
intends this precondition to prevent the method from being applied if
there have been any changes to the representation data.
强验证器只能在表示 bit-for-bit 相同时具有相同的值。但是,如果正如您所说,“其他数据可能很重要”超出了项目哈希,那么您当时无法决定强 ETag
。因此,在这种情况下,您根本无法进行项目散列并与规范保持一致。
当然,您可以决定额外的数据 不 重要,在这种情况下您仍然可以进行项目散列并与规范保持一致。但这避免了您为响应哈希想法给出的一个缺点(“我们不能只从数据库中提取项目来检查 ETag,因为我们没有额外的数据”)。
换句话说:你需要一个强大的 ETag
来避免丢失更新,并且需要强大的验证器 must change “每当在 200 的有效载荷主体中可以观察到的表示数据发生变化时(确定)对 GET 的响应。”因此,要构建 ETag
,您必须知道在任何情况下响应 GET
所知道的一切,因此在响应层中执行此操作没有任何缺点。
我们正在构建 REST API,我们将 ETag 用于两种用途:
- 通过允许客户端避免重新加载资源(对我们来说并不重要)来节省带宽
- 解决并发问题(丢失更新问题)
从实际的角度来看,我想知道用什么来计算 ETag。
项目哈希
我们正在使用响应中发送的(json 项目 object 转储的散列。这很好用。检查 PUT 请求很容易:从数据库中提取项目、计算哈希、比较。然而,它使关注点的分离有点“漏洞”:从项目构建响应的层有点与负责 ETag 计算的层交错。此外,附加数据(响应 headers)可能很重要,如果确实如此,发送 304 仅仅因为项目本身没有改变而 headers 确实可能不合适。
响应哈希
另一种方法是在发送之前对响应进行哈希处理。这样做可以使计算部分的 ETag 层更加清晰。但是,在 PUT 请求中,我们不能只从数据库中提取项目来检查 ETag,因为我们没有额外的数据。
第一种方法(计算项目哈希)似乎适用于案例 2 并发问题。第二种方法(计算有效负载哈希,包括元数据,headers)适用于情况 1 节省带宽。
将响应的每一位(包括 headers)放入请求中似乎是正确的,因为那里的每个更改都可能相关并需要客户端刷新其缓存。但是我不知道如何使用这样的 ETag 管理 PUT 或 DELETE 请求的并发。
从实际的角度来看,我们应该使用项目哈希还是响应哈希?我们如何用其中之一来处理这两种情况?
根据您的描述,我认为响应哈希是唯一有意义的。
首先,为了使用条件请求来避免丢失更新问题,验证器 need to be strong.
An origin server MUST use the strong comparison function when comparing entity-tags for If-Match (Section 2.3.2), since the client intends this precondition to prevent the method from being applied if there have been any changes to the representation data.
强验证器只能在表示 bit-for-bit 相同时具有相同的值。但是,如果正如您所说,“其他数据可能很重要”超出了项目哈希,那么您当时无法决定强 ETag
。因此,在这种情况下,您根本无法进行项目散列并与规范保持一致。
当然,您可以决定额外的数据 不 重要,在这种情况下您仍然可以进行项目散列并与规范保持一致。但这避免了您为响应哈希想法给出的一个缺点(“我们不能只从数据库中提取项目来检查 ETag,因为我们没有额外的数据”)。
换句话说:你需要一个强大的 ETag
来避免丢失更新,并且需要强大的验证器 must change “每当在 200 的有效载荷主体中可以观察到的表示数据发生变化时(确定)对 GET 的响应。”因此,要构建 ETag
,您必须知道在任何情况下响应 GET
所知道的一切,因此在响应层中执行此操作没有任何缺点。