AIP-235

Batch methods: Delete

Some APIs need to allow users to delete a set of resources in a single transaction. A batch delete method provides this functionality.

Guidance

Batch delete methods are specified using the following pattern:

rpc BatchDeleteBooks(BatchDeleteBooksRequest) returns (google.protobuf.Empty) {
  option (google.api.http) = {
    post: "/v1/{parent=publishers/*}/books:batchDelete"
    body: "*"
  };
}
  • The RPC’s name must begin with BatchDelete. The remainder of the RPC name should be the plural form of the resource being deleted.
  • The request message must match the RPC name, with a -Request suffix.
  • The response message should be google.protobuf.Empty.
    • If the resource is soft deleted, the response message should be a response message containing the updated resources.
    • In the event that the request may take a significant amount of time, the response message must be a google.longrunning.Operation which resolves to the correct response.
  • The HTTP verb must be POST (not DELETE).
  • The HTTP URI must end with :batchDelete.
  • The URL path should represent the collection for the resource, matching the collection used for simple CRUD operations. If the operation spans parents, a dash (-) may be accepted as a wildcard.
  • The body clause in the google.api.http annotation should be "*".
  • The operation should be atomic: it should fail for all resources or succeed for all resources (no partial success).
    • If the operation covers multiple locations and at least one location is down, the operation must fail.

Request message

The request for a batch delete method should be specified with the following pattern:

message BatchDeleteBooksRequest {
  // The parent resource shared by all books being deleted.
  // Format: publishers/{publisher}
  // If this is set, the parent of all of the books specified in `names`
  // must match this field.
  string parent = 1;

  // The names of the books to delete.
  // A maximum of 1000 books can be deleted in a batch.
  // format: publishers/{publisher}/books/{book}
  repeated string names = 2;
}
  • A parent field should be included. If a caller sets this field, and the parent collection in the name of any resource being deleted does not match, the request must fail.
    • This field should be required if only 1 parent per request is allowed.
  • The request message must include a repeated field which accepts the resource names specifying the resources to delete. The field should be named names.
  • Other fields besides name may be “hoisted” from the standard Delete request. There is no way to allow for these fields to accept different values for different resources; if this is needed, use the alternative request message form.
  • The request message must not contain any other required fields, and should not contain other optional fields except those described in this or another AIP.
  • The comment above the names field should document the maximum number of requests allowed.
  • Filter-based matching must not be supported.

Request message containing standard delete request messages

If the standard Delete request message contains a field besides the resource name that needs to be different between different resources being requested, the batch message may alternatively hold a repeated field of the standard Delete request message. This is generally discouraged unless your use case really requires it.

The request for a batch delete method should be specified with the following pattern:

message BatchDeleteBooksRequest {
  // The parent resource shared by all books being deleted.
  // Format: publishers/{publisher}
  // If this is set, the parent of all of the books specified in the
  // DeleteBookRequest messages must match this field.
  string parent = 1;

  // The requests specifying the books to delete.
  // A maximum of 1000 books can be deleted in a batch.
  repeated DeleteBookRequest requests = 2;
}
  • A parent field should be included. If a caller sets this field, and the parent collection in the name of any resource being deleted does not match, the request must fail.
    • This field should be required if only 1 parent per request is allowed.
  • The request message must include a repeated field which accepts the request messages specifying the resources to delete, as specified for standard Delete methods. The field should be named requests.
  • Other fields may be “hoisted” from the standard Delete request, which means that the field can be set at either the batch level or child request level. Similar to parent, if both the batch level and child request level are set for the same field, the values must match.
    • Fields which must be unique cannot be hoisted (e.g. etag).
  • The request message must not contain any other required fields, and should not contain other optional fields except those described in this or another AIP.
  • The comment above the requests field should document the maximum number of requests allowed.
  • Filter-based matching must not be supported.

Filter-based matching disallowed

  • Filter-based matching must not be supported, because it makes it too easy for users to accidentally delete important data.

Response message (soft-delete only)

In the case where a response message is necessary because the resource is soft-deleted, the response should be specified with the following pattern:

message BatchDeleteBooksResponse {
  // Books deleted.
  repeated Book books = 1;
}
  • The response message must include one repeated field corresponding to the resources that were soft-deleted.

Changelog

  • 2019-10-11: Changed the primary recommendation to specify a repeated string instead of a repeated standard Delete message. Moved the original recommendation into its own section.
  • 2019-09-11: Fixed the wording about which child field the parent field should match.
  • 2019-08-01: Changed the examples from “shelves” to “publishers”, to present a better example of resource ownership.