Skip to content

Commit

Permalink
fix(methods): remove management plane, require strong consistency (ae…
Browse files Browse the repository at this point in the history
…p-dev#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.
  • Loading branch information
toumorokoshi authored Nov 2, 2024
1 parent 5631df6 commit d5f3482
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 31 deletions.
22 changes: 13 additions & 9 deletions aep/general/0121/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,21 @@ patterns, such as database transactions, import and export, or data analysis.

### Strong Consistency

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

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

Examples include:
- An output-only field that takes so long to reach a steady-state that it would
negatively impact the user experience of the request (e.g. an hour-long instantiation
of a VM cluster).

Examples of strong consistency include:

- Following a successful create that is is latest mutation on a resource, a get
request for a resource **must** return the resource.
Expand Down Expand Up @@ -141,7 +146,6 @@ turn do not increase resource management complexity.
[get]: ./0131.md
[list]: ./0132.md
[long-running-requests]: ./0151.md
[management plane]: ./0111.md#management-plane
[output only]: ./0203.md#output-only
[rest]: https://en.wikipedia.org/wiki/Representational_state_transfer
[resource references]: ./0122.md#fields-representing-another-resource
Expand Down
22 changes: 8 additions & 14 deletions aep/general/0133/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,7 @@ rpc CreateBook(CreateBookRequest) returns (Book) {
- There **should** be exactly one `google.api.method_signature` annotation,
with a value of `"parent,{resource},id"`, or "`"parent,{resource}"` if the
resource ID is not required.
- If the API is operating on the [management plane][], the operation should have
[strong consistency][]: the completion of a create operation **must** mean
that all user-settable values and the existence of the resource have reached a
steady-state and reading resource state returns a consistent response.
- The operation **must** have [strong consistency][].

{% tab oas %}

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

Create methods implement a common request message pattern:

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

### User-specified IDs

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

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

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

An API **may** allow the `id` field to be optional, and give the resource a
system-generated ID if one is not specified.
Expand Down Expand Up @@ -233,7 +228,6 @@ path and use it in references from other resources.
[aep-203]: ./0203.md
[aep-210]: ./0210.md
[data plane]: ./0111.md#data-plane
[management plane]: ./0111.md#management-plane
[errors]: ./0193.md
[field_behavior]: ./203.md
[Declarative clients]: ./0003.md#declarative-clients
Expand Down
47 changes: 45 additions & 2 deletions aep/general/0134/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Update methods are specified using the following pattern:
itself.
- The method **should** support partial resource update, and the HTTP verb
**should** be `PATCH`.
- The operation **must** have [strong consistency][].

{% tab proto %}

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

{% endtabs %}

### Create or update

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

If the service uses client-assigned resource paths, `Update` methods **may**
expose a `bool allow_missing` field, which will cause the method to succeed in
the event that the user attempts to update a resource that is not present (and
will create the resource in the process):

{% tab proto %}

```proto
message UpdateBookRequest {
// The book to update.
//
// The book's `path` field is used to identify the book to be updated.
// Format: publishers/{publisher}/books/{book}
Book book = 1 [(google.api.field_behavior) = REQUIRED];

// The list of fields to be updated.
google.protobuf.FieldMask update_mask = 2;

// If set to true, and the book is not found, a new book will be created.
// In this situation, `update_mask` is ignored.
bool allow_missing = 3;
}
```

{% tab oas %}

**Note:** OAS example not yet written.

{% endtabs %}

More specifically, the `allow_missing` flag triggers the following behavior:

- If the method call is on a resource that does not exist, the resource is
created. All fields are applied regardless of any provided field mask.
- However, if any required fields are missing or fields have invalid values,
an `INVALID_ARGUMENT` error is returned.
- If the method call is on a resource that already exists, and all fields
match, the existing resource is returned unchanged.
- If the method call is on a resource that already exists, only fields declared
in the field mask are updated.

The user **must** have the update permissions to call `Update` even with
`allow_missing` set to `true`.

### Etags

An API may sometimes need to allow users to send update requests which are
Expand Down Expand Up @@ -312,7 +356,6 @@ unless `allow_missing` is set to `true`.
[aep-203]: ./0203.md
[create]: ./0133.md
[errors]: ./0193.md
[management plane]: ./0111.md#management-plane
[permission-denied]: ./0193.md#permission-denied
[state fields]: ./0216.md
[strong consistency]: ./0121.md#strong-consistency
Expand Down
9 changes: 4 additions & 5 deletions aep/general/0135/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ The Delete method **should** succeed if and only if a resource was present and
was successfully deleted. If the resource did not exist, the method **should**
send a `404 Not found` (`NOT_FOUND`) error.

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

Delete methods are specified using the following pattern:

Expand Down Expand Up @@ -230,7 +230,6 @@ exist, the service **must** error with `404 Not found` (`NOT_FOUND`).
[aep-203]: ./0203.md
[aep-214]: ./0214.md
[aep-216]: ./0216.md
[management plane]: ./0111.md#management-plane
[strong consistency]: ./0121.md#strong-consistency
[etag]: ./0134.md#etags
[RFC 9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-delete
Expand Down
3 changes: 2 additions & 1 deletion aep/general/0154/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ current ETag. If the `If-Match` header value does not match the ETag, the
service **must** reply with an HTTP 412 error.

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

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

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

0 comments on commit d5f3482

Please sign in to comment.