什么是生成ETag的有效且处理廉价的算法?

RPM*_*984 5 c# rest etag http nancy

我有一个REST API(内置在Nancy中,在ASP.NET上运行)可以返回一个JSON对象,如下所示:

{
   id: "1",
   name: "Fred",
   reviews: [
     {
        id: "10",
        content: "I love Stack Overflow"
     }
   ]
}
Run Code Online (Sandbox Code Playgroud)

注意这个对象不是一个直接的实体,而是一个表示.

通常,我会使用DB中实体的最后修改/时间戳作为ETag,然后当它得到更新时,ETag会更新.简单.

但在这种情况下,如果用户没有改变,但第一次评论的内容发生了变化,该怎么办?使用上述ETag逻辑,它不会改变.我们在这里有一个案例,其中表示包括多个实体,我正试图找到一种方法来唯一地识别它.

所以我需要以某种方式识别该表示(这是一个简单的C#POCO,存储在Redis缓存中).

以下是我最初的想法:

  • Object.GetHashCode().不会起作用,因为内存引用总是不同的.
  • 内存流对象,SHA1哈希它.每次都要花钱.
  • 在添加/更新缓存之前,创建一个用于ETag的GUID并将其存储在缓存中.然后,当高速缓存得到刷新时(在前面的例子中),将生成一个新的GUID并更新ETag.这种方法的问题是我将我的ETag机制绑定到我的缓存实现(因此没有松散耦合).

有没有人能想到一种廉价/有效的方法来做到这一点,理想情况是在全球范围内?(例如Object,或基础对象,而不是每个实体/资源的特定ETag生成逻辑).

非常感谢!

Jes*_*pez 1

我认为散列方法还不错。我会考虑一些极其高效的哈希算法,例如 MurmurHash3(128 位版本)和 xxHash(64 位版本)。这是一种在全球范围内实现这一目标的有效方法,但不幸的是它并不是最便宜的。您可以在此处此处找到 C# 实现。

您说数据库中的每个实体都有一个修改后的时间戳。如果模型由多个实体组成,则可以从实体时间戳导出模型 ETag。模型 ETag 将是实体时间戳的串联。这种方法更有效,但你不能在全球范围内做到这一点,你需要为每个模型编写特定的代码。