Skip to content

Commit 59e3dd4

Browse files
authored
feat(AIP-121): adding guidance around consistency (#1060)
Google clients have implicit requirements around the consistency today, but it is not explicitly stated in the AIPs. Clarifying the guidance around consistency requirements.
1 parent f5cd3b0 commit 59e3dd4

4 files changed

Lines changed: 74 additions & 14 deletions

File tree

aip/general/0121.md

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,38 @@ the standard methods. Custom methods offer the same design freedom as
9494
traditional RPC APIs, which can be used to implement common programming
9595
patterns, such as database transactions, import and export, or data analysis.
9696

97+
### Strong Consistency
98+
99+
For methods that operate on the [management plane][], the completion of those
100+
operations (either successful or with an error, LRO or synchronous) **must**
101+
mean that the state of the resource's existence and all user-settable values
102+
have reached a steady-state.
103+
104+
[output only][] values unrelated to the resource [state][] **should** also have
105+
reached a steady-state. for values that are related to the resource [state][].
106+
107+
Examples include:
108+
109+
- Following a successful create that is is latest mutation on a resource, a get
110+
request for a resource **must** return the resource.
111+
- Following a successful update that is the latest mutation on a resource, a get
112+
request for a resource **must** return the final values from the update
113+
request.
114+
- Following a successful delete that is the latest mutation on a resource, a get
115+
request for a resource **must** return `NOT_FOUND` (or the resource with the
116+
`DELETED` state value in the case of [soft delete][])
117+
118+
Clients of resource-oriented APIs often need to orchestrate multiple operations
119+
in sequence (e.g. create resource A, create resource B which depends on A), and
120+
ensuring that resources immediately reflect steady user state after an operation
121+
is complete ensures clients can rely on method completion as a signal to begin
122+
the next operation.
123+
124+
[output only][] fields ideally would follow the same guidelines, but as
125+
these fields can often represent a resources live state, it's sometimes
126+
necessary for these values to change after a successful mutation operation to
127+
reflect a state change.
128+
97129
### Stateless protocol
98130

99131
As with most public APIs available today, resource-oriented APIs **must**
@@ -129,23 +161,27 @@ This requirement does not apply to relationships that are expressed via
129161
[output only][] fields, as they do not require the user to specify the values
130162
and in turn do not increase resource management complexity.
131163

132-
[rest]: https://en.wikipedia.org/wiki/Representational_state_transfer
133-
[rpc]: https://en.wikipedia.org/wiki/Remote_procedure_call
134-
[stateless protocol]: https://en.wikipedia.org/wiki/Stateless_protocol
135-
[get]: ./0131.md
136-
[list]: ./0132.md
137164
[create]: ./0133.md
138-
[update]: ./0134.md
139-
[delete]: ./0135.md
140165
[custom methods]: ./0136.md
166+
[delete]: ./0135.md
141167
[directed acyclic graph]: https://en.wikipedia.org/wiki/Directed_acyclic_graph
142-
[resource references]: ./0122.md#fields-representing-another-resource
168+
[get]: ./0131.md
169+
[list]: ./0132.md
170+
[management plane]: ./0111.md#management-plane
143171
[output only]: ./0203.md#output-only
172+
[rest]: https://en.wikipedia.org/wiki/Representational_state_transfer
173+
[resource references]: ./0122.md#fields-representing-another-resource
174+
[rpc]: https://en.wikipedia.org/wiki/Remote_procedure_call
144175
[singleton resources]: ./0156.md
176+
[soft delete]: ./0164.md
177+
[state]: ./0216.md
178+
[stateless protocol]: https://en.wikipedia.org/wiki/Stateless_protocol
179+
[update]: ./0134.md
145180

146181

147182
## Changelog
148183

184+
- **2023-08-24**: Added guidance on consistency guarantees of methods.
149185
- **2023-07-23**: Clarify stateless protocol definition.
150186
- **2023-01-21**: Explicitly require matching schema across standard methods.
151187
- **2022-12-19**: Added a section requiring Get and List.

aip/general/0133.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ rpc CreateBook(CreateBookRequest) returns (Book) {
6060
- There **should** be exactly one `google.api.method_signature` annotation,
6161
with a value of `"parent,{resource},{resource}_id"`, or "`"parent,{resource}"`
6262
if the resource ID is not required.
63+
- If the API is operating on the [management plane][], the operation should have
64+
[strong consistency][]: the completion of a create operation **must** mean
65+
that all user-settable values and the existence of the resource have reached a
66+
steady-state and reading resource state returns a consistent response.
6367

6468
### Request message
6569

@@ -128,9 +132,9 @@ to done if the request is effectively immediate.
128132

129133
An API **must** allow a user to specify the ID component of a resource (the last
130134
segment of the resource name) on creation if the API is operating on the
131-
[Management Plane][].
135+
[management plane][].
132136

133-
On the [Data Plane][], an API **should** allow a user to specify the ID.
137+
On the [data plane][], an API **should** allow a user to specify the ID.
134138
Exceptional cases should have the following behavior:
135139

136140
- The data plane resource allows identical records without a need to
@@ -203,15 +207,17 @@ name and use it in references from other resources.
203207
[aip-155]: ./0155.md
204208
[aip-203]: ./0203.md
205209
[aip-210]: ./0210.md
206-
[Data Plane]: ./0111.md#data-plane
207-
[Management Plane]: ./0111.md#management-plane
210+
[data plane]: ./0111.md#data-plane
211+
[management plane]: ./0111.md#management-plane
208212
[errors]: ./0193.md
209213
[field_behavior]: ./203.md
210214
[Declarative clients]: ./0009.md#declarative-clients
211215
[permission-denied]: ./0193.md#permission-denied
216+
[strongly consistent]: ./0121.md#strong-consistency
212217

213218
## Changelog
214219

220+
- **2023-08-24**: Adding consistency requirement.
215221
- **2023-05-11**: Changing guidance around resource_id to a must.
216222
- **2022-11-04**: Referencing aggregated error guidance in AIP-193, similar to
217223
other CRUDL AIPs.

aip/general/0134.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,14 @@ rpc UpdateBook(UpdateBookRequest) returns (Book) {
5858
- There **must** be a `body` key in the `google.api.http` annotation, and it
5959
**must** map to the resource field in the request message.
6060
- All remaining fields **should** map to URI query parameters.
61-
- There **should** be exactly one `google.api.method_signature` annotation,
62-
with a value of `"{resource},update_mask"`.
61+
- There **should** be exactly one `google.api.method_signature` annotation, with
62+
a value of `"{resource},update_mask"`.
63+
- If the API is operating on the [management plane][], the operation should have
64+
[strong consistency][]: the completion of an update operation **must** mean
65+
that all user-settable values and the existence of the resource have reached a
66+
steady-state and reading resource state returns a consistent response.
67+
68+
6369

6470
**Note:** Unlike the other four standard methods, the URI path here references
6571
a nested field (`book.name`) in the example. If the resource field has a word
@@ -277,13 +283,16 @@ does not exist, the service **must** error with `NOT_FOUND` (HTTP 404) unless
277283
[aip-203]: ./0203.md
278284
[create]: ./0133.md
279285
[errors]: ./0193.md
286+
[management plane]: ./0111.md#management-plane
280287
[permission-denied]: ./0193.md#permission-denied
281288
[state fields]: ./0216.md
289+
[strong consistency]: ./0121.md#strong-consistency
282290
[required]: ./0203.md#required
283291
[optional]: ./0203.md#optional
284292

285293
## Changelog
286294

295+
- **2023-08-26**: Adding consistency requirement.
287296
- **2023-07-17**: Make `update_mask` name guidance a **must**.
288297
- **2022-11-04**: Aggregated error guidance to AIP-193.
289298
- **2022-06-02**: Changed suffix descriptions to eliminate superfluous "-".

aip/general/0135.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty) {
5353
- There **should** be exactly one `google.api.method_signature` annotation,
5454
with a value of `"name"`. If an etag or force field are used, they **may** be
5555
included in the signature.
56+
- If the API is operating on the [Management Plane][], the operation should have
57+
[strong consistency][]: the completion of a delete operation **must** mean
58+
that the existence of the resource has reached a steady-state and reading
59+
resource state returns a consistent response.
60+
61+
5662

5763
The Delete method **should** succeed if and only if a resource was present and
5864
was successfully deleted. If the resource did not exist, the method **should**
@@ -222,6 +228,8 @@ exist, the service **must** error with `NOT_FOUND` (HTTP 404) unless
222228
[aip-203]: ./0203.md
223229
[aip-214]: ./0214.md
224230
[aip-216]: ./0216.md
231+
[management plane]: ./0111.md#management-plane
232+
[strong consistency]: ./0121.md#strong-consistency
225233
[etag]: ./0134.md#etags
226234

227235
## Further reading
@@ -231,6 +239,7 @@ exist, the service **must** error with `NOT_FOUND` (HTTP 404) unless
231239

232240
## Changelog
233241

242+
- **2023-08-24**: Adding consistency requirement.
234243
- **2022-06-02:** Changed suffix descriptions to eliminate superfluous "-".
235244
- **2022-02-02**: Changed eTag error from `FAILED_PRECONDITION` to `ABORTED` making it consistent with change to [AIP-154][] & [AIP-134][etag] on 2021-03-05.
236245
- **2020-10-06**: Added guidance for declarative-friendly resources.

0 commit comments

Comments
 (0)