Skip to content

Apply

In REST APIs, it is customary to make a PUT request to a resource’s URI (for example, /v1/publishers/{publisher}/books/{book}) in order to create or replace a resource.

Resource-oriented design honors this pattern through the Apply method. These operations accept the resource and its path, which it uses to create or replace the resource. The operation returns the final resource.

Also see the update method, with guidance on how to implement PATCH requests.

Guidance

APIs should provide an apply method for a resource unless it is not valuable for users to do so. Clients should also consider using update methods instead to ensure forwards compatible requests (see PATCH and PUT).

Operation

Apply methods are specified using the following pattern:

  • The HTTP verb must be PUT.
  • Some resources take longer to be applied than is reasonable for a regular API request. In this situation, the API should use a long-running operation.
  • The operation must have strong consistency.
  • The HTTP URI path of the PUT method must be the resource path.
rpc ApplyBook ( ApplyBookRequest ) returns ( Book ) {
option (google.api.http) = {
put: "/{path=publishers/*/books/*}",
body: "book"
};
}
  • The request message must match the method name, with a Request suffix.

  • 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},id", or “"parent,{resource}" if the resource ID is not required.

  • The method’s name must begin with the word Apply. The remainder of the method name should be the singular form of the resource being applied.

  • The request’s path field must map to the URI path.

  • The path field must be the only variable in the URI path.

Requests

Apply methods implement a common request message pattern:

  • The resource must be included and must map to the HTTP request body.
  • The request schema must not contain any other required fields and should not contain other optional fields except those described in this or another AEP.
message ApplyBookRequest {
// The globally unique identifier for the resource
string path = 10018 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = { type: "bookstore.example.com/book" }
];
// The resource to perform the operation on.
Book book = 10015 [(google.api.field_behavior) = REQUIRED];
}
  • A path field specifying the path of the resource must be included.

Responses

  • The response must be the resource itself. There is no separate response schema.
    • The response should include the fully-populated resource, and must include any fields that were provided unless they are input only (see field behavior).
message Book {
option (google.api.resource) = {
type: "bookstore.example.com/book",
pattern: [ "publishers/{publisher}/books/{book}" ],
plural: "books",
singular: "book"
};
// A Author.
message Author {
// Field for firstName.
string firstName = 1;
// Field for lastName.
string lastName = 2;
}
// Field for author.
repeated Author author = 5;
// Field for isbn.
repeated string isbn = 1 [(google.api.field_behavior) = REQUIRED];
// Field for price.
float price = 2 [(google.api.field_behavior) = REQUIRED];
// Field for published.
bool published = 3 [(google.api.field_behavior) = REQUIRED];
// Field for edition.
int32 edition = 4;
// Field for path.
string path = 10000;
}

Errors

See errors, in particular when to use PERMISSION_DENIED and NOT_FOUND errors.

PATCH and PUT

Note that PUT requests with fields missing in the resource may result in overwriting values in the resource with existing values. For that reason, AEP-compliant APIs generally use the PATCH HTTP verb.

See AEP-134’s patch and put for more information.

Interface Definitions

rpc ApplyBook ( ApplyBookRequest ) returns ( Book ) {
option (google.api.http) = {
put: "/{path=publishers/*/books/*}",
body: "book"
};
}
message ApplyBookRequest {
// The globally unique identifier for the resource
string path = 10018 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = { type: "bookstore.example.com/book" }
];
// The resource to perform the operation on.
Book book = 10015 [(google.api.field_behavior) = REQUIRED];
}
message Book {
option (google.api.resource) = {
type: "bookstore.example.com/book",
pattern: [ "publishers/{publisher}/books/{book}" ],
plural: "books",
singular: "book"
};
// A Author.
message Author {
// Field for firstName.
string firstName = 1;
// Field for lastName.
string lastName = 2;
}
// Field for author.
repeated Author author = 5;
// Field for isbn.
repeated string isbn = 1 [(google.api.field_behavior) = REQUIRED];
// Field for price.
float price = 2 [(google.api.field_behavior) = REQUIRED];
// Field for published.
bool published = 3 [(google.api.field_behavior) = REQUIRED];
// Field for edition.
int32 edition = 4;
// Field for path.
string path = 10000;
}

Further reading

  • For ensuring idempotency in Apply methods, see idempotency.
  • For naming resources involving Unicode, see unicode.