Skip to content

Commit d5f3482

Browse files
authored
fix(methods): remove management plane, require strong consistency (#222)
The introduction of the concept of management plane and data plane and it's subjective definition in the AEPs was leading to ambiguous guidance. Removing the mention of those concepts until a clearer criteria can be established. This change requires that a decision must be made for strong consistency. As operations that are not strongly consistent can result in manual per-resource patches for declarative clients, require strong consistency for all standard methods.
1 parent 5631df6 commit d5f3482

File tree

5 files changed

+72
-31
lines changed

5 files changed

+72
-31
lines changed

aep/general/0121/aep.md.j2

+13-9
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,21 @@ patterns, such as database transactions, import and export, or data analysis.
8383

8484
### Strong Consistency
8585

86-
For methods that operate on the [management plane][], the completion of those
87-
operations (either successful or with an error,
88-
[long-running][long-running-requests] or synchronous) **must** mean that the
89-
state of the resource's existence and all user-settable values have reached a
90-
steady-state.
86+
A method is strongly consistent if, upon completion of a request of that method
87+
(regardless of whether the request is successful,
88+
[long-running][long-running-requests] or synchronous), all user-settable fields
89+
will return the same value on any subsequent requests until another request
90+
which mutates the resource is completed.
9191

92-
[Output only][output only] values unrelated to the resource [state][]
93-
**should** also have reached a steady-state.
92+
[Output only][output only] fields unrelated to the resource [state][] **should**
93+
also return the same value on each subsequent request until another request
94+
which mutates the resource is completed.
9495

95-
Examples include:
96+
- An output-only field that takes so long to reach a steady-state that it would
97+
negatively impact the user experience of the request (e.g. an hour-long instantiation
98+
of a VM cluster).
99+
100+
Examples of strong consistency include:
96101

97102
- Following a successful create that is is latest mutation on a resource, a get
98103
request for a resource **must** return the resource.
@@ -141,7 +146,6 @@ turn do not increase resource management complexity.
141146
[get]: ./0131.md
142147
[list]: ./0132.md
143148
[long-running-requests]: ./0151.md
144-
[management plane]: ./0111.md#management-plane
145149
[output only]: ./0203.md#output-only
146150
[rest]: https://en.wikipedia.org/wiki/Representational_state_transfer
147151
[resource references]: ./0122.md#fields-representing-another-resource

aep/general/0133/aep.md.j2

+8-14
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ rpc CreateBook(CreateBookRequest) returns (Book) {
5757
- There **should** be exactly one `google.api.method_signature` annotation,
5858
with a value of `"parent,{resource},id"`, or "`"parent,{resource}"` if the
5959
resource ID is not required.
60-
- If the API is operating on the [management plane][], the operation should have
61-
[strong consistency][]: the completion of a create operation **must** mean
62-
that all user-settable values and the existence of the resource have reached a
63-
steady-state and reading resource state returns a consistent response.
60+
- The operation **must** have [strong consistency][].
6461

6562
{% tab oas %}
6663

@@ -72,8 +69,7 @@ rpc CreateBook(CreateBookRequest) returns (Book) {
7269

7370
Create methods implement a common request message pattern:
7471

75-
- An `id` field **must** be included for management plane resources, and
76-
**should** be included for data plane resources.
72+
- An `id` field **should** be supported.
7773
- The resource field **must** be included and **must** map to the POST body.
7874
- The request message **must not** contain any other required fields and
7975
**should not** contain other optional fields except those described in this
@@ -148,16 +144,15 @@ rpc CreateBook(CreateBookRequest) returns (aep.api.Operation) {
148144

149145
### User-specified IDs
150146

151-
An API **must** allow a user to specify the ID component of a resource (the
152-
last segment of the resource path) on creation if the API is operating on the
153-
[management plane][].
147+
An API **should** allow a user to specify the ID component of a resource: not
148+
doing so introduces a non-idempotent request in the API, as sending the same
149+
payload results in creating a new resource each time.
154150

155-
On the [data plane][], an API **should** allow a user to specify the ID.
156151
Exceptional cases should have the following behavior:
157152

158-
- The data plane resource allows identical records without a need to
159-
disambiguate between the two (e.g. rows in a table with no primary key).
160-
- The data plane resource will not be exposed in [Declarative clients][].
153+
- The resource allows identical records without a need to disambiguate between
154+
the two (e.g. rows in a table with no primary key).
155+
- The resource will not be exposed in [Declarative clients][].
161156

162157
An API **may** allow the `id` field to be optional, and give the resource a
163158
system-generated ID if one is not specified.
@@ -233,7 +228,6 @@ path and use it in references from other resources.
233228
[aep-203]: ./0203.md
234229
[aep-210]: ./0210.md
235230
[data plane]: ./0111.md#data-plane
236-
[management plane]: ./0111.md#management-plane
237231
[errors]: ./0193.md
238232
[field_behavior]: ./203.md
239233
[Declarative clients]: ./0003.md#declarative-clients

aep/general/0134/aep.md.j2

+45-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Update methods are specified using the following pattern:
2929
itself.
3030
- The method **should** support partial resource update, and the HTTP verb
3131
**should** be `PATCH`.
32+
- The operation **must** have [strong consistency][].
3233

3334
{% tab proto %}
3435

@@ -190,7 +191,6 @@ rpc UpdateBook(UpdateBookRequest) returns (aep.api.Operation) {
190191

191192
{% endtabs %}
192193

193-
### Create or update
194194

195195
If the service uses client-assigned resource paths, `Update` methods **may**
196196
expose a `bool allow_missing` field, which will cause the method to succeed in
@@ -229,6 +229,50 @@ More specifically, the `allow_missing` flag triggers the following behavior:
229229
The user **must** have the update permissions to call `Update` even with
230230
`allow_missing` set to `true`.
231231

232+
If the service uses client-assigned resource paths, `Update` methods **may**
233+
expose a `bool allow_missing` field, which will cause the method to succeed in
234+
the event that the user attempts to update a resource that is not present (and
235+
will create the resource in the process):
236+
237+
{% tab proto %}
238+
239+
```proto
240+
message UpdateBookRequest {
241+
// The book to update.
242+
//
243+
// The book's `path` field is used to identify the book to be updated.
244+
// Format: publishers/{publisher}/books/{book}
245+
Book book = 1 [(google.api.field_behavior) = REQUIRED];
246+
247+
// The list of fields to be updated.
248+
google.protobuf.FieldMask update_mask = 2;
249+
250+
// If set to true, and the book is not found, a new book will be created.
251+
// In this situation, `update_mask` is ignored.
252+
bool allow_missing = 3;
253+
}
254+
```
255+
256+
{% tab oas %}
257+
258+
**Note:** OAS example not yet written.
259+
260+
{% endtabs %}
261+
262+
More specifically, the `allow_missing` flag triggers the following behavior:
263+
264+
- If the method call is on a resource that does not exist, the resource is
265+
created. All fields are applied regardless of any provided field mask.
266+
- However, if any required fields are missing or fields have invalid values,
267+
an `INVALID_ARGUMENT` error is returned.
268+
- If the method call is on a resource that already exists, and all fields
269+
match, the existing resource is returned unchanged.
270+
- If the method call is on a resource that already exists, only fields declared
271+
in the field mask are updated.
272+
273+
The user **must** have the update permissions to call `Update` even with
274+
`allow_missing` set to `true`.
275+
232276
### Etags
233277

234278
An API may sometimes need to allow users to send update requests which are
@@ -312,7 +356,6 @@ unless `allow_missing` is set to `true`.
312356
[aep-203]: ./0203.md
313357
[create]: ./0133.md
314358
[errors]: ./0193.md
315-
[management plane]: ./0111.md#management-plane
316359
[permission-denied]: ./0193.md#permission-denied
317360
[state fields]: ./0216.md
318361
[strong consistency]: ./0121.md#strong-consistency

aep/general/0135/aep.md.j2

+4-5
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ The Delete method **should** succeed if and only if a resource was present and
1717
was successfully deleted. If the resource did not exist, the method **should**
1818
send a `404 Not found` (`NOT_FOUND`) error.
1919

20-
If the API is operating on the [Management Plane][], the method should have
21-
[strong consistency][]: the completion of a delete method **must** mean that
22-
the existence of the resource has reached a steady-state and reading resource
23-
state returns a consistent `404 Not found` (`NOT_FOUND`) response.
20+
The method **must** have [strong consistency][]: the completion of a delete
21+
method **must** mean that the existence of the resource has reached a
22+
steady-state and reading resource state returns a consistent `404 Not found`
23+
(`NOT_FOUND`) response.
2424

2525
Delete methods are specified using the following pattern:
2626

@@ -230,7 +230,6 @@ exist, the service **must** error with `404 Not found` (`NOT_FOUND`).
230230
[aep-203]: ./0203.md
231231
[aep-214]: ./0214.md
232232
[aep-216]: ./0216.md
233-
[management plane]: ./0111.md#management-plane
234233
[strong consistency]: ./0121.md#strong-consistency
235234
[etag]: ./0134.md#etags
236235
[RFC 9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-delete

aep/general/0154/aep.md.j2

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ current ETag. If the `If-Match` header value does not match the ETag, the
5151
service **must** reply with an HTTP 412 error.
5252

5353
If the user omits the `If-Match` header, the service **should** permit the
54-
request. However, services with strong consistency or parallelism requirements
54+
request. However, services with [strong consistency][] or parallelism requirements
5555
**may** require users to send ETags all the time and reject the request with an
5656
HTTP 400 error if it does not contain an ETag.
5757

@@ -113,3 +113,4 @@ not equivalent to the old one).
113113
- **2019-09-23**: Changed the title to "resource freshness validation".
114114

115115
[rfc 7232]: https://tools.ietf.org/html/rfc7232#section-2.3
116+
[strong consistency]: ./0121.md#strong-consistency

0 commit comments

Comments
 (0)