Dataverse Web API - 本·格里鲍多

作者:API传播员 · 2025-12-05 · 阅读时间:5分钟

你是否注意到,每次从 Dataverse Web API 获取实体时,总会返回一个神秘的“@odata.etag”值?本文将深入探讨 ETag 的作用及其在 Web API 中的实际应用。


什么是 ETag?

ETag 是“实体标签”(Entity Tag)的缩写,它是记录的版本标识符。通过 ETag,您可以判断某个资源是否发生了变化。如果两次获取相同资源时返回的 ETag 值一致,则可以确认该资源在语义上没有变化。

例如:

GET {{webApiUrl}}contacts(b8d3f910-1896-eb11-b1ac-000d3a3ac80d)?$select=firstname
(include the "always include" headers)

Response:
{
  "@odata.context": "{{webApiUrl}}$metadata#contacts(firstname)/$entity",
  "@odata.etag": "W/"842270"",
  "firstname": "Yvonne",
  "contactid": "b8d3f910-1896-eb11-b1ac-000d3a3ac80d"
}

在上述响应中,@odata.etag 提供了资源的版本标识符。如果您昨天获取了某个实体并收到 ETag W/"1377902",今天再次获取该实体时 ETag 仍然是 W/"1377902",则说明该实体没有发生变化。


有条件 GET 请求

通过设置 If-None-Match 请求头,您可以让服务器判断资源是否发生变化,而无需在客户端进行比较。例如:

GET {{webApiUrl}}contacts(b8d3f910-1896-eb11-b1ac-000d3a3ac80d)
If-None-Match: W/"1377902"
(include the other "always include" headers)
  • 如果资源未发生变化:服务器返回 304 Not Modified 响应,表示客户端已有最新数据。
  • 如果资源已发生变化:服务器返回更新后的资源数据。

这种方式将 ETag 的比较逻辑从客户端转移到了服务器端,减少了不必要的数据传输。


有条件更新

在构建 API 客户端时,您可能需要在用户编辑数据时确保数据的版本一致性。假设用户在周五获取了某个实体的数据,周一进行编辑时,该实体可能已被其他用户修改。为避免覆盖其他用户的更改,可以使用乐观并发控制。

通过在 PATCH 请求中设置 If-Match 请求头,您可以确保只有当实体的 ETag 未变化时,更新才会成功。例如:

PATCH {{webApiUrl}}contacts(b8d3f910-1896-eb11-b1ac-000d3a3ac80d)
If-Match: W/"1377902"
(include the other "always include" headers)

{ ... JSON with column edits goes here ... }
  • 如果 ETag 匹配:更新成功。
  • 如果 ETag 不匹配:返回 412 Precondition Failed 响应,提示数据已被修改。

有条件删除

类似于更新操作,删除操作也可以通过 If-Match 请求头确保数据一致性。例如:

DELETE {{webApiUrl}}contacts(b8d3f910-1896-eb11-b1ac-000d3a3ac80d)
If-Match: W/"1377902"
(include the other "always include" headers)
  • 如果 ETag 匹配:删除操作成功。
  • 如果 ETag 不匹配:返回 412 Precondition Failed 响应,防止删除已被修改的实体。

控制 PATCH 行为

默认情况下,PATCH 请求会更新指定的实体,如果实体不存在,则会创建一个新实体。但有时您可能希望限制这种行为。例如,您只想更新现有实体,而不希望创建新实体。

通过设置 If-MatchIf-None-Match 请求头,可以控制 PATCH 的行为:

  • 仅更新:设置 If-Match 请求头,确保实体存在且未被修改。
  • 仅插入:设置 If-None-Match 请求头,确保实体不存在。

使用 ETag 的注意事项

在使用 ETag 时,请注意以下细节:

  • 比较方式:ETag 的比较仅支持相等性检查,不能进行大于或小于的比较。
  • 算法变化:ETag 的生成算法可能会随着系统升级而变化,因此不同的 ETag 不一定表示资源已被修改。
  • 缓存影响:为了防止意外缓存,每个请求都应包含 If-None-Match 请求头。如果没有其他值可用,可以设置为字符串 "null"
  • 适用范围:ETag 仅适用于单个实体。当使用 $expand 查询选项或 Prefer: odata.include-annotations 请求头时,服务器不会根据 ETag 返回 304 Not Modified 响应。
  • 启用条件:ETag 默认适用于所有自定义实体和部分内置实体,但某些系统实体可能不支持 ETag。

总结

ETag 是 Dataverse Web API 中一个强大的功能,能够帮助开发者实现高效的数据同步和并发控制。通过合理使用 If-MatchIf-None-Match 请求头,您可以优化 API 调用,减少不必要的数据传输,同时确保数据的一致性。

原文链接: https://bengribaudo.com/blog/tag/dataverse-web-api