AIP-165

Criteria-based delete

Occasionally, an API may need to provide a mechanism to delete a large number of resources based on some set of filter parameters, rather than requiring the individual resource name of the resources to be deleted.

This is a rare case, reserved for situations where users need to delete thousands or more resources at once, in which case the normal Batch Delete pattern (AIP-235) becomes unwieldy and inconvenient.

Guidance

Important: Most APIs should use only Delete (AIP-135) or Batch Delete (AIP-235) for deleting resources, and should not implement deleting based on criteria. This is because deleting is generally irreversible and this type of operation makes it easy for a user to accidentally lose significant amounts of data.

An API may implement a Purge method to permit deleting a large number of resources based on a filter string; however, this should only be done if the Batch Delete (AIP-235) pattern is insufficient to accomplish the desired goal:

rpc PurgeBooks(PurgeBooksRequest) returns (google.longrunning.Operation) {
  option (google.api.http) = {
    post: "/v1/{parent=publishers/*}/books:purge"
    body: "*"
  }
  option (google.longrunning.operation_info) = {
    response_type: "PurgeBooksResponse"
    metadata_type: "PurgeBooksMetadata"
  };
}
  • The HTTP verb must be POST, and the body must be "*".
  • The parent field should be included in the URI. If the API wishes to support deletion across multiple parents, it should accept the - character consistent with AIP-159.
  • The response type must be a google.longrunning.Operation (see AIP-151).

Request message

Purge methods implement a common request message pattern:

message PurgeBooksRequest {
  // The publisher to purge books from.
  // To purge books across publishers, send "publishers/-".
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "library-example.googleapis.com/Book"
    }];

  // A filter matching the books to be purged.
  string filter = 2 [(google.api.field_behavior) = REQUIRED];

  // Actually perform the purge.
  // If `force` is set to false, the method will return a sample of
  // resource names that would be deleted.
  bool force = 3;
}
  • The filter field should be required, and must follow the same semantics as in List methods (see AIP-132).
  • The force field must be included. If it is not set, the API must return a count of the resources that would be deleted as well as a sample of those resources, without actually performing the deletion.

Response message

Purge methods implement a common response message pattern:

message PurgeBooksResponse {
  // The number of books that this request deleted (or, if `force` is false,
  // the number of books that will be deleted).
  int32 purge_count = 1;

  // A sample of the resource names of books that will be deleted.
  // Only populated if `force` is set to false.
  repeated string purge_sample = 2;
}
  • The purge_count field should be included, and provide the number of resources that were deleted (or would be deleted). This count may be an estimate similar to total_size in AIP-158 (but the service should document this if so).
  • The purge_sample field should be included: If force is false, it should provide a sample of resource names that will be deleted. If force is true, this field should not be populated.
    • The sample should be a sufficient size to catch clearly obvious mistakes: A good rule of thumb is 100. The API should document the size, and should document that it is a maximum (it is possible to send fewer).
    • The sample may be random or may be deterministic (such as the first matched resource names). The API should document which approach is used.

Note: Even if purge_count and purge_sample are not included, the force field must still be included in the request.