This chapter will discuss how to use custom methods for API designs.
Custom methods refer to API methods besides the 5 standard methods. They should only be used for functionality that cannot be easily expressed via standard methods. In general, API designers should choose standard methods over custom methods whenever feasible. Standard Methods have simpler and well-defined semantics that most developers are familiar with, so they are easier to use and less error prone. Another advantage of standard methods is the API platform has better understanding and support for standard methods, such as billing, error handling, logging, monitoring.
A custom method can be associated with a resource, a collection, or a service. It may take an arbitrary request and return an arbitrary response, and also supports streaming request and response.
Custom method names must follow method naming conventions.
HTTP mapping
For custom methods, they should use the following generic HTTP mapping:
https://service.name/v1/some/resource/name:customVerb
The reason to use :
instead of /
to separate the custom verb from the
resource name is to support arbitrary paths. For example, undelete a file
can map to POST /files/a/long/file/name:undelete
The following guidelines shall be applied when choosing the HTTP mapping:
- Custom methods should use HTTP
POST
verb since it has the most flexible semantics, except for methods serving as an alternative get or list which may useGET
when possible. (See third bullet for specifics.) - Custom methods should not use HTTP
PATCH
, but may use other HTTP verbs. In such cases, the methods must follow the standard HTTP semantics for that verb. - Notably, custom methods using HTTP
GET
must be idempotent and have no side effects. For example custom methods that implement special views on the resource should use HTTPGET
. - The request message field(s) receiving the resource name of the resource or collection with which the custom method is associated should map to the URL path.
- The URL path must end with a suffix consisting of a colon followed by the custom verb.
- If the HTTP verb used for the custom method allows an HTTP request
body (this applies to
POST
,PUT
,PATCH
, or a custom HTTP verb), the HTTP configuration of that custom method must use thebody: "*"
clause and all remaining request message fields shall map to the HTTP request body. - If the HTTP verb used for the custom method does not accept an HTTP
request body (
GET
,DELETE
), the HTTP configuration of such method must not use thebody
clause at all, and all remaining request message fields shall map to the URL query parameters.
WARNING: If a service implements multiple APIs, the API producer must carefully create the service configuration to avoid custom verb conflicts between APIs.
// This is a service level custom method.
rpc Watch(WatchRequest) returns (WatchResponse) {
// Custom method maps to HTTP POST. All request parameters go into body.
option (google.api.http) = {
post: "/v1:watch"
body: "*"
};
}
// This is a collection level custom method.
rpc ClearEvents(ClearEventsRequest) returns (ClearEventsResponse) {
option (google.api.http) = {
post: "/v3/events:clear"
body: "*"
};
}
// This is a resource level custom method.
rpc CancelEvent(CancelEventRequest) returns (CancelEventResponse) {
option (google.api.http) = {
post: "/v3/{name=events/*}:cancel"
body: "*"
};
}
// This is a batch get custom method.
rpc BatchGetEvents(BatchGetEventsRequest) returns (BatchGetEventsResponse) {
// The batch get method maps to HTTP GET verb.
option (google.api.http) = {
get: "/v3/events:batchGet"
};
}
Use Cases
Some additional scenarios where custom methods may be the right choice:
- Reboot a virtual machine. The design alternatives could be "create a reboot resource in collection of reboots" which feels disproportionately complex, or "virtual machine has a mutable state which the client can update from RUNNING to RESTARTING" which would open questions as to which other state transitions are possible. Moreover, reboot is a well-known concept that can translate well to a custom method which intuitively meets developer expectations.
- Send mail. Creating an email message should not necessarily send it (draft). Compared to the design alternative (move a message to an "Outbox" collection) custom method has the advantage of being more discoverable by the API user and models the concept more directly.
- Promote an employee. If implemented as a standard
update
, the client would have to replicate the corporate policies governing the promotion process to ensure the promotion happens to the correct level, within the same career ladder etc. - Batch methods. For performance critical methods, it may be useful to provide custom batch methods to reduce per-request overhead. For example, accounts.locations.batchGet.
A few examples where a standard method is a better fit than a custom method:
- Query resources with different query parameters (use standard
list
method with standard list filtering). - Simple resource property change (use standard
update
method with field mask). - Dismiss a notification (use standard
delete
method).
Common Custom Methods
The curated list of commonly used or useful custom method names is below. API designers should consider these names before introducing their own to facilitate consistency across APIs.
Method Name | Custom verb | HTTP verb | Note |
---|---|---|---|
Cancel |
:cancel |
POST |
Cancel an outstanding operation, such as operations.cancel . |
BatchGet |
:batchGet |
GET |
Batch get of multiple resources. See details in the description of List. |
Move |
:move |
POST |
Move a resource from one parent to another, such as folders.move . |
Search |
:search |
GET |
Alternative to List for fetching data that does not adhere to List semantics, such as services.search . |
Undelete |
:undelete |
POST |
Restore a resource that was previously deleted, such as services.undelete . The recommended retention period is 30-day. |