Skip to content

Commit dd986da

Browse files
authored
feat(AIP-136): require GET/POST, use parent instead of singular (#1093)
The resource singular is a harder pattern to recognize as it requires a consumer to know the resource singular beforehand. Using parent aligns it with other collection-oriented methods. Further explanation for the rationale is in the changes for AIP-136. fixes #1089
1 parent 71a9442 commit dd986da

1 file changed

Lines changed: 49 additions & 13 deletions

File tree

aip/general/0136.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,42 @@ services. The bullets below apply in all three cases.
4444
- The name **must not** contain prepositions ("for", "with", etc.).
4545
- The verb in the name **should not** contain any of the standard method verbs ([Get][],
4646
[List][], [Create][], [Update][], [Delete][]).
47-
- The HTTP method for custom methods **should** usually be `POST`, unless the
48-
custom method maps more strongly to another HTTP verb.
49-
- Custom methods that serve as an alternative to get or list methods (such as
50-
`Search`) **should** use `GET`. These methods **must** be idempotent and
51-
have no side effects.
52-
- Custom methods **should not** use `PATCH` or `DELETE`.
47+
- The HTTP method **must** be `GET` or `POST`:
48+
- `GET` **must** be used for methods retrieving data or resource state.
49+
- `POST` **must** be used if the method has side effects or mutates resources
50+
or data.
5351
- The HTTP URI **must** use a `:` character followed by the custom verb
5452
(`:archive` in the above example), and the verb in the URI **must** match the
5553
verb in the name of the RPC.
5654
- If word separation is required, `camelCase` **must** be used.
5755
- The `body` clause in the `google.api.http` annotation **should** be `"*"`.
58-
- However, if using `GET` or `DELETE`, the `body` clause **must** be absent.
59-
- Custom methods **should** usually take a request message matching the RPC
56+
- However, if using `GET`, the `body` clause **must** be absent.
57+
- Custom methods **should** take a request message matching the RPC
6058
name, with a `Request` suffix.
61-
- Custom methods **should** usually return a response message matching the RPC
59+
- Custom methods **should** return a response message matching the RPC
6260
name, with a `Response` suffix.
6361
- When operating on a specific resource, a custom method **may** return the
6462
resource itself.
6563

64+
65+
### Resource-based custom methods
66+
67+
Custom methods **must** operate on a resource if the API can be modeled
68+
as such:
69+
70+
```proto
71+
// Archives the given book.
72+
rpc ArchiveBook(ArchiveBookRequest) returns (ArchiveBookResponse) {
73+
option (google.api.http) = {
74+
post: "/v1/{name=publishers/*/books/*}:archive"
75+
body: "*"
76+
};
77+
}
78+
```
79+
80+
- The parameter for the resource's name **must** be called `name`, and
81+
be the only variable in the URI path.
82+
6683
### Collection-based custom methods
6784

6885
While most custom methods operate on a single resource, some custom methods
@@ -72,15 +89,14 @@ While most custom methods operate on a single resource, some custom methods
7289
// Sorts the books from this publisher.
7390
rpc SortBooks(SortBooksRequest) returns (SortBooksResponse) {
7491
option (google.api.http) = {
75-
post: "/v1/{publisher=publishers/*}/books:sort"
92+
post: "/v1/{parent=publishers/*}/books:sort"
7693
body: "*"
7794
};
7895
}
7996
```
8097

81-
- If the collection has a parent, the field name in the request message
82-
**should** be the target resource's singular noun (`publisher` in the above
83-
example). If word separators are necessary, `snake_case` **must** be used.
98+
- The collection's parent resource **must** be called `parent`, and
99+
be the only variable in the URI path.
84100
- The collection key (`books` in the above example) **must** be literal.
85101

86102
### Stateless methods
@@ -119,6 +135,24 @@ An exception to this is for rarely-used, fundamentally imperative operations,
119135
such as a `Move` or `Rename` operation, for which there would not be an
120136
expectation of declarative support.
121137

138+
## Rationale
139+
140+
### HTTP path
141+
142+
Similar to standard methods, a custom method that operates on a resource or
143+
collection needs a `name` or `parent` parameter to indicate the resource that it
144+
operates on. This convention allows clients to map custom methods to the
145+
appropriate resource.
146+
147+
### HTTP methods
148+
149+
Allowing both `GET` and `POST` HTTP verbs allows a clear distinction for
150+
which methods do not mutate data, and which ones do. Methods that only
151+
read data have first-class concepts in some clients (DataSources in
152+
Terraform) and clearly indicate to a user which methods can be called
153+
without risk of runtime impact.
154+
155+
122156
[get]: ./0131.md
123157
[list]: ./0132.md
124158
[create]: ./0133.md
@@ -127,6 +161,8 @@ expectation of declarative support.
127161

128162
## Changelog
129163

164+
- **2023-05-09:** Adding guidance for POST and GET, require parent instead of
165+
the resource singular.
130166
- **2023-03-02:** Explicitly discourage use of standard method verbs.
131167
- **2022-06-02:** Changed suffix descriptions to eliminate superfluous "-".
132168
- **2020-10-06:** Added declarative-friendly guidance.

0 commit comments

Comments
 (0)