AIP-133

Standard methods: Create

In REST APIs, it is customary to make a POST request to a collection’s URI (for example, /v1/publishers/{publisher}/books) in order to create a new resource within that collection.

Resource-oriented design (AIP-121) honors this pattern through the Create method. These RPCs accept the parent collection and the resource to create (and potentially some other parameters), and return the created resource.

Guidance

APIs should generally provide a create method for resources unless it is not valuable for users to do so. The purpose of the create method is to create a new resource in an already-existing collection.

Create methods are specified using the following pattern:

rpc CreateBook(CreateBookRequest) returns (Book) {
  option (google.api.http) = {
    post: "/v1/{parent=publishers/*}/books"
    body: "book"
  };
  option (google.api.method_signature) = "parent,book";
}
  • The RPC’s name must begin with the word Create. The remainder of the RPC name should be the singular form of the resource being created.
  • The request message must match the RPC name, with a -Request suffix.
  • The response message must be the resource itself. There is no CreateBookResponse.
    • If the create RPC is long-running, the response message must be a google.longrunning.Operation which resolves to the resource itself.
  • The HTTP verb must be POST.
  • The collection where the resource is being added should map to the URL path.
    • The collection’s parent resource should be called parent, and should be the only variable in the URI path.
    • The collection identifier (books in the above example) must be literal.
  • There must be a body key in the google.api.http annotation, and it must map to the resource field in the request message.
    • All remaining fields should map to URI query parameters.
  • There should be exactly one google.api.method_signature annotation, with a value of "parent,{resource}" (unless the method supports user-specified IDs).

Request message

Create methods implement a common request message pattern:

message CreateBookRequest {
  // The parent resource where this book will be created.
  // Format: publishers/{publisher}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "library-example.googleapis.com/Book"
    }];

  // The book to create.
  Book book = 2 [(google.api.field_behavior) = REQUIRED];
}
  • A parent field must be included unless the resource being listed is a top-level resource. It should be called parent.
    • The field should be annotated as required.
    • The field should identify the resource type of the resource being listed.
  • The resource field must be included and must map to the POST body.
  • 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.

Long-running create

Some resources take longer to create a resource than is reasonable for a regular API request. In this situation, the API should use a long-running operation instead:

rpc CreateBook(CreateBookRequest) returns (google.longrunning.Operation) {
  option (google.api.http) = {
    post: "/v1/{parent=publishers/*}/books"
  };
  option (google.longrunning.operation_info) = {
    response_type: "Book"
    metadata_type: "OperationMetadata"
  }
}
  • The response type must be set to the resource (what the return type would be if the RPC was not long-running).
  • Both the response_type and metadata_type fields must be specified.

User-specified IDs

Sometimes, an API needs to allow a client to specify the ID component of a resource (the last segment of the resource name) on creation. This is common if users are allowed to choose that portion of their resource names.

For example:

// Using user-settable IDs.
publishers/lacroix/books/les-miserables

// Using system-generated IDs.
publishers/012345678-abcd-cdef/books/12341234-5678-abcd

Create RPCs may support this behavior by providing a string {resource}_id field on the request message:

message CreateBookRequest {
  // The parent resource where this book will be created.
  // Format: publishers/{publisher}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "library-example.googleapis.com/Book"
    }];

  // The book to create.
  Book book = 2 [(google.api.field_behavior) = REQUIRED];

  // The ID to use for the book, which will become the final component of
  // the book's resource name.
  //
  // This value should be 4-63 characters, and valid characters
  // are /[a-z][0-9]-/.
  string book_id = 3;
}
  • The {resource}_id field must exist on the request message, not the resource itself.
    • The field may be required or optional. If it is required, it should include the corresponding annotation.
  • The name field on the resource must be ignored.
  • There should be exactly one google.api.method_signature annotation on the RPC, with a value of "parent,{resource},{resource}_id".
  • The documentation should explain what the acceptable format is, and the format should follow the guidance for resource name formatting in AIP-122.

Further reading

  • For ensuring idempotency in Create methods, see AIP-155.
  • For naming resources involving Unicode, see AIP-210.

Changelog

  • 2019-10-18: Added guidance on annotations.
  • 2019-08-01: Changed the examples from “shelves” to “publishers”, to present a better example of resource ownership.
  • 2019-06-10: Added guidance for long-running create.
  • 2019-05-29: Added an explicit prohibition on arbitrary fields in standard methods.