编号 | 154 |
---|---|
原文链接 | AIP-154: Resource freshness validation |
状态 | 批准 |
创建日期 | 2019-07-24 |
更新日期 | 2019-07-24 |
在资源上执行某类操作之前,API往往需要确认客户端和服务器一致认定资源当前状态。例如,两个进程并行更新同一个资源可能产生竞态条件,后一个进程可能会“覆盖”前面进程的工作。
ETag给出了解决之道。服务器根据资源当前内容发送校验和,当客户端把校验和送回来时,服务器可以确保校验和匹配后处理请求。
指南
如果需要客户端在执行某些请求之前拥有最新的资源,资源 可以 包含 etag
域:
// A representation of a book.
message Book {
// Other fields...
// This checksum is computed by the server based on the value of other
// fields, and may be sent on update and delete requests to ensure the
// client has an up-to-date value before proceeding.
string etag = 99;
}
- etag域 必须 是字符串, 必须 命名为
etag
。 - 资源 的etag域 不应 包含任何行为注解。
- etag域 必须 由服务器输出,并且值 应当 符合RFC 7232。
- 如果用户发送的etag与当前etag值匹配,服务 必须 允许该请求(除非存在其他导致失败的原因)。
- 如果用户发送的etag与当前etag值不匹配,服务 必须 发送
ABORTED
错误应答(除非存在优先级更高的错误。例如,如果用户未获授权则返回PERMISSION_DENIED
)。 - 如果用户没有发送etag值,服务 应当 允许该请求。然而,具有强一致性或并行性要求的服务 可以 要求用户必须发送etag,拒绝缺少etag的请求,返回
INVALID_ARGUMENT
错误。
注意 ETag值 应当 按照RFC 7232要求包含引号。例如,
"foo"
是有效的etag值,而foo
不是。
声明友好资源
声明友好资源(AIP-128) 必须 包含 etag
域。
请求方法的Etag
有时,etag需要包含在请求消息中,而非资源本身。例如, Update
标准方法可以“借用”资源上的 etag
域,但 Delete
标准方法不行:
message DeleteBookRequest {
// The name of the book.
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
type: "library.googleapis.com/Book"
}];
// The current etag of the book.
// If an etag is provided and does not match the current etag of the book,
// deletion will be blocked and an ABORTED error will be returned.
string etag = 2 [(google.api.field_behavior) = OPTIONAL];
}
在请求消息中, etag
域 应当 包含行为注解——要么是 REQUIRED
,要么是 OPTIONAL
。有关更多信息,请参考AIP-203。
etag
域也 可以 用于自定义方法,类似前文示例。
强验证和弱验证
ETag可以是“强验证的”或“弱验证的”:
- 强验证的etag意味着具有相同etag的两个资源是逐字节相同的。
- 弱验证的etag意味着具有相同etag的两个资源是等同的,但可能在一些服务认为不重要的方面有所不同。
资源 可以 根据需要选择强验证或弱验证,但 应当 以文档记录具体行为。此外,根据RFC 7232规定,弱验证etag 必须 具有 W/
前缀。
进一步阅读
- 关于客户端库如何在失败时重试,请参考AIP-194。
修订记录
- 2021-04-01 将
FAILED_PRECONDITION
引用改为ABORTED
。 - 2021-03-05 将etag错误从
FAILED_PRECONDITION
(即HTTP 400)改为ABORTED
(即HTTP 409)。 - 2020-10-06 添加声明友好资源要求。
- 2020-09-02 明确其他错误可能优先于
FAILED_PRECONDITION
etag不匹配。 - 2020-09-02 添加关于请求消息中的etag的指难。
- 2019-09-23 将标题改为“资源时效性验证”。