1- # Custom operations
1+ # Custom methods
22
3- Services use custom operations to provide a means to express arbitrary actions
4- that are difficult to model using only the standard operations. Custom
5- operations are important because they provide a means for an API's vocabulary
6- to adhere to user intent.
3+ Resource oriented design (AEP-121) uses custom methods to provide a means to
4+ express actions that are difficult to model using only the standard methods.
5+ Custom methods are important because they provide a means for an API's
6+ vocabulary to adhere to user intent.
77
88## Guidance
99
10- Custom operations **should** only be used for functionality that can not be
11- easily expressed via standard operations; prefer standard operations if
12- possible, due to their consistent semantics. (Of course, this only applies if
13- the functionality in question actually conforms to the normal semantics; it is
14- _not_ a good idea to contort things to endeavor to make the standard operations
15- "sort of work".)
10+ Custom methods **should** only be used for functionality that can not be
11+ expressed via standard methods; prefer standard methods if possible, due to
12+ their consistent semantics. However, APIs **should not** contort things to
13+ endeavor to make the standard methods "sort of work".
1614
17- While custom operations vary widely in how they are designed, many principles
15+ While custom methods vary widely in how they are designed, many principles
1816apply consistently:
1917
18+ - The HTTP method for custom methods **should** be selected based on the
19+ semantics described by [RFC 7231 section 4.3] and [RFC 5789] for `PATCH`. In
20+ practice, the vast majority of custom methods **should** use `POST` or `GET`.
21+ - Custom methods that serve as an alternative to get or list methods (such as
22+ `Search`) **should** use `GET`, and require no request body. These methods
23+ **must** be idempotent and have no state changes or side effects (they
24+ should be safe as defined in [RFC 7231 section 4.2.1][]).
25+ - Custom methods **should not** use `PATCH` or `DELETE`.
26+ - The HTTP URI **must** use a `:` character followed by the custom verb
27+ (`:archive` in the above example), and the verb in the URI **must** match the
28+ verb in the name of the RPC.
29+ - If word separation is required, `camelCase` **must** be used.
30+
2031{% tab proto %}
2132
2233{% sample 'library.proto' , 'rpc ArchiveBook' %}
2334
2435- The name of the RPC **should** be a verb followed by a noun.
2536 - The name **must not** contain prepositions ("for", "with", etc.).
26- - The HTTP method for custom operations **should** usually be `POST`, unless
27- the custom method maps more strongly to another HTTP verb.
28- - Custom operations that serve as an alternative to get or list operations
29- (such as `Search`) **should** use `GET`. These operations **must** be
30- idempotent and have no state changes or side effects (they should be safe
31- as defined in [RFC 7231][]).
32- - Custom operations **should not** use `PATCH` or `DELETE`.
33- - The HTTP URI **must** use a `:` character followed by the custom verb
34- (`:archive` in the above example), and the verb in the URI **must** match the
35- verb in the name of the RPC.
36- - If word separation is required, `camelCase` **must** be used.
3737- The `body` clause in the `google.api.http` annotation **should** be `"*"`.
3838 - However, if using `GET` or `DELETE`, the `body` clause **must** be absent.
39- - Custom operations **should ** usually take a request message matching the RPC
40- name, with a - `Request` suffix.
41- - Custom operations **should** usually return a response message matching the
42- RPC name, with a - `Response` suffix.
39+ - Custom methods **must ** take a request message exactly matching the RPC name,
40+ with a `Request` suffix. For example, `ArchiveBookRequest` .
41+ - Custom methods **should** return a response message exactly matching the RPC
42+ name, with a `Response` suffix. For example, `ArchiveBookResponse` .
4343 - When operating on a specific resource, a custom method **may** return the
4444 resource itself.
4545
4646{% tab oas %}
4747
4848{% sample 'library.oas.yaml' , '/publishers/{publisherId}/books/{bookId}:archive' %}
4949
50- - The `operationId` **should** be a verb followed by a noun.
51- - The `operationId` **must not** contain prepositions ("for", "with", etc.).
52- - The HTTP method for custom operations **should** usually be `POST`, unless
53- the custom method maps more strongly to another HTTP verb.
54- - Custom operations that serve as an alternative to get or list operations
55- (such as `Search`) **should** use `GET`, and require no request body. These
56- operations **must** be idempotent and have no state changes or side effects
57- (they should be safe as defined in [RFC 7231][]).
58- - Custom operations **should not** use `PATCH` or `DELETE`.
59- - The HTTP URI **must** use a `:` character followed by the custom verb
60- (`:archive` in the above example), and the verb in the URI **must** match the
61- verb in the `operationId`.
62- - If word separation is required, `camelCase` **must** be used.
50+ - The name of the RPC **should** be a verb followed by a noun.
51+ - The name of the RPC **must not** contain prepositions ("for", "with",
52+ etc.).
6353
6454{% endtabs %}
6555
6656**Note:** The pattern above shows a custom method that operates on a specific
67- resource. Custom operations can be associated with resources, collections, or
57+ resource. Custom methods can be associated with resources, collections, or
6858services.
6959
70- ### Collection-based custom operations
60+ ### Resource-based custom methods
61+
62+ Custom methods **must** operate on a resource if the API can be modeled as
63+ such:
64+
65+ {% tab proto %}
66+
67+ {% sample 'library.proto' , 'rpc ArchiveBook' %}
68+
69+ - The parameter for the resource's path **must** be called `path`, and **must**
70+ be the only variable in the URI path.
71+
72+ {% tab oas %}
73+
74+ **Note:** OAS example not yet written.
75+
76+ {% endtabs %}
77+
78+ ### Collection-based custom methods
7179
72- While most custom operations operate on a single resource, some custom
73- operations **may** operate on a collection instead:
80+ While most custom methods operate on a single resource, some custom methods
81+ **may** operate on a collection instead:
7482
7583{% tab proto %}
7684
@@ -83,15 +91,14 @@ operations **may** operate on a collection instead:
8391{% endtabs %}
8492
8593- If the collection has a parent, the field name in the request message
86- **should** be the target resource's singular noun (`publisher` in the above
87- example). If word separators are necessary, `snake_case` **must** be used.
94+ **should** be `parent`.
8895- The collection key (`books` in the above example) **must** be literal.
8996
90- ### Stateless operations
97+ ### Stateless methods
9198
92- Some custom operations are not attached to resources at all. These operations
93- are generally _stateless_: they accept a request and return a response, and
94- have no permanent effect on data within the API.
99+ Some custom methods are not attached to resources at all. These methods are
100+ generally _stateless_: they accept a request and return a response, and have no
101+ permanent effect on data within the API.
95102
96103{% tab proto %}
97104
@@ -110,17 +117,21 @@ have no permanent effect on data within the API.
110117- The URI **should** place both the verb and noun after the `:` separator
111118 (avoid a "faux collection key" in the URI in this case, as there is no
112119 collection). For example, `:translateText` is preferable to `text:translate`.
113- - Stateless operations **must** use `POST` if they involve billing.
120+ - Stateless methods **must** use `POST` if they involve billing.
114121
115122### Declarative-friendly resources
116123
117- Declarative-friendly resources usually **should not** employ custom operations
118- (except specific declarative-friendly custom operations discussed in other
119- AEPs), because declarative-friendly tools are unable to automatically determine
120- what to do with them.
124+ Declarative-friendly resources usually **should not** employ custom methods
125+ (except specific declarative-friendly custom methods discussed in other AEPs),
126+ because declarative-friendly tools are unable to automatically determine what
127+ to do with them.
121128
122129An exception to this is for rarely-used, fundamentally imperative operations,
123130such as a `Move`, `Rename`, or `Restart` operation, for which there would not
124131be an expectation of declarative support.
125132
126- [rfc 7231]: https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.1
133+ <!-- prettier-ignore-start -->
134+ [rfc 5789]: https://datatracker.ietf.org/doc/html/rfc5789
135+ [rfc 7231 section 4.2.1]: https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.1
136+ [rfc 7231 section 4.3]: https://datatracker.ietf.org/doc/html/rfc7231#section-4.3
137+ <!-- prettier-ignore-end -->
0 commit comments