tommwq.work/aip

AIP-135 标准方法:Delete

· [tommwq@126.com]
编号 135
原文链接 https://google.aip.dev/135
状态 批准
创建日期 2019-01-24
更新日期 2019-01-24

REST API通常向资源URI(如 /v1/publishers/{publisher}/books/{book} )发出 DELETE 请求,删除资源。

面向资源设计(AIP-121)提供Delete方法,遵循这一模式。这些接口接受代表资源的URI,通常返回空白应答。

指南

API通常 应当 为资源提供Delete方法,除非对用户没有意义。

Delete方法使用以下模式规定:

rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
  option (google.api.http) = {
    delete: "/v1/{name=publishers/*/books/*}"
  };
  option (google.api.method_signature) = "name";
}
  • 接口名字 必须Delete 开头,其余部分 应当 是资源消息名字的单数形式。
  • 请求消息 必须 与 接口名字一致,并带有 Request 后缀。
  • 应答消息 应当google.protobuf.Empty
    • 如果资源使用软删除,应答消息 应当 是资源本身。
    • 如果删除接口是耗时删除,应答消息 必须google.longrunning.Operation ,解析为正确的应答。
  • HTTP动词 必须DELETE
  • 接收资源名字的请求消息域 应当 映射到URI路径。
    • 应当 称为 name
    • name应当 是URI路径中唯一的变量。其余参数 应当 映射到URI查询参数。
  • 不得google.api.http 注解中包含 body 键。
  • 应当 只有一个 google.api.method_signature 注解,值为 "name" 。如果使用了 etagforce 域,它们 可以 包含在签名中。
  • 如果 API 在 [管理平面][] 上操作,操作应具有 [强一致性][]:删除操作的完成 必须 意味着资源的存在已达到稳定状态,并且读取资源状态返回一致的应答。
  • 如果存在子资源,API 必须FAILED_PRECONDITION 错误失败。如果需要强制删除父资源和子资源,请参阅级联删除指南。
    • 如果唯一的子资源类型是 [单例][aip-156],*必须* 允许删除,因为单例的生命周期与其父资源绑定。即使同一父资源有多个不同的单例资源类型,这也适用。

Delete方法 应当 仅在资源存在并成功删除时成功。如果资源不存在,方法 应当 发送 NOT_FOUND 错误。

请求消息

Delete方法实现了下面的通用请求消息模式:

message DeleteBookRequest {
  // The name of the book to delete.
  // Format: publishers/{publisher}/books/{book}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "library.googleapis.com/Book"
    }];
}
  • 请求 必须 包含 name 域,域名字 应当name
  • 域注释 应当 记录资源模式。
  • 请求消息 不得 包含任何其他必需域, 不应 包含其他可选域,本AIP或其他AIP要求的除外。

软删除

注意: 本节内容已迁移到独立文档,以提供更全面的说明:AIP-164

耗时删除

有些资源在删除时消耗的时间要比API通常的合理应答时间长。此时API 应当 使用耗时操作:

rpc DeleteBook(DeleteBookRequest) returns (google.longrunning.Operation) {
  option (google.api.http) ~ {
    delete: "/v1/{name~publishers/*/books/*}"
  };
  option (google.longrunning.operation_info) ~ {
    response_type: "google.protobuf.Empty"
    metadata_type: "OperationMetadata"
  };
}
  • 如果接口不是耗时操作,应答类型 必须 设置为适当的返回类型。对于大多数删除接口是 google.protobuf.Empty ,对于软删除则是资源自身(AIP-164)。
  • 必须 指定 response_typemetadata_type 域(即使它们是 google.protobuf.Empty 类型)。

级联删除

有时用户可能需要删除资源和所有的下级资源。然而由于删除通常是永久性的,确认用户不是误操作非常重要,因为恢复被删除的下级资源可能非常困难。

如果API删除的资源可能拥有下级资源,API 应当 在请求中提供 bool force 域,用户设置该域,明确要求级联删除。

message DeletePublisherRequest {
  // The name of the publisher to delete.
  // Format: publishers/{publisher}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "library.googleapis.com/Publisher"
    }];

  // If set to true, any books from this publisher will also be deleted.
  // (Otherwise, the request will only work if the publisher has no books.)
  bool force = 2;
}

如果 force 域设定为 false (或没有设定), 当下级资源存在时,API 必须 返回 FAILED_PRECONDITION 错误。

保护删除

有时用户可能需要确认待删除资源没有受到任何修改。如果资源提供了etag,删除请求 可以 接受etag(作为必需域或可选域):

message DeleteBookRequest {
  // The name of the book to delete.
  // Format: publishers/{publisher}/books/{book}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "library.googleapis.com/Book"
    }];

  // Optional. The etag of the book.
  // If this is provided, it must match the server's etag.
  string etag = 2;
}

如果客户端提供了etag,但与服务器计算的值不匹配,API 必须 返回 ABORTED 错误码。

注意: 声明友好资源(AIP-128必须 为删除请求提供 etag 域。

存在时删除

如果服务使用客户端分配的资源名字, Delete 方法 可以 提供 bool allow_missing 域,当用户尝试删除一个不存在的资源时,API也可以成功执行(此时请求不会引发实际操作):

message DeleteBookRequest {
  // The book to delete.
  // Format: publishers/{publisher}/books/{book}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "library.googleapis.com/Book"
  ];

  // If set to true, and the book is not found, the request will succeed
  // but no action will be taken on the server
  bool allow_missing = 2;
}

更具体地说, allow_missing 标志引发下列行为:

  • 如果方法调用的是不存在的资源,请求没有实际操作。
    • etag 域被忽略。
  • 如果方法调用的是存在的资源,资源将被删除(受其他检查的约束)。

注意: 声明友好资源(AIP-128应当 提供 bool allow_missing 域。

错误

如果用户没有权限访问资源,无论资源是否存在,服务 必须 返回 PERMISSION_DENIED (HTTP 403)错误。权限检查 必须 在资源存在性检查之前进行。

如果用户有适当的权限,但请求的资源不存在,服务 必须 返回 NOT_FOUND (HTTP 404)错误,除非 allow_missing 设定为 true

进一步阅读

  • 关于软删除和恢复删除,请参考AIP-164
  • 关于使用过滤器批量删除多个资源,请参考AIP-165

修订记录

  • 2024-06-11 添加缺失 force 域时删除上级资源的行为。
  • 2023-08-24 添加一致性要求。
  • 2022-06-02 修改后缀描述,消除多余的“-”。
  • 2022-02-02 将etag错误从 FAILED_PRECONDITION 改为 ABORTED ,与2021-03-05对AIP-154AIP-134的修订一致。
  • 2020-10-06 添加声明友好资源指南。
  • 2020-10-06 添加允许对缺失资源进行无实际操作删除的指南。
  • 2020-10-06 将软删除和恢复删除指南移至新的AIP-164
  • 2020-06-08 添加返回完整资源数据的指南。
  • 2020-02-03 添加错误场景指南。
  • 2019-10-18 添加注释指南。
  • 2019-08-01 将示例从“shelves”改为“publishers”,提供更好的资源所有权示例。
  • 2019-06-10 添加耗时更新指南。
  • 2019-05-29 添加禁止在标准方法中使用任意域的明确禁令。