From cc3d693c513d44cf339214a02530f947d58edd61 Mon Sep 17 00:00:00 2001 From: Tim Burks Date: Thu, 11 Jul 2024 12:31:40 -0700 Subject: [PATCH 1/2] feat(server-modified-values): initial import of aip-129 --- aep/general/0129/aep.md.j2 | 138 +++++++++++++++++++++++++++++++++++++ aep/general/0129/aep.yaml | 7 ++ 2 files changed, 145 insertions(+) create mode 100644 aep/general/0129/aep.md.j2 create mode 100644 aep/general/0129/aep.yaml diff --git a/aep/general/0129/aep.md.j2 b/aep/general/0129/aep.md.j2 new file mode 100644 index 00000000..4f11f6e1 --- /dev/null +++ b/aep/general/0129/aep.md.j2 @@ -0,0 +1,138 @@ +# Server-Modified Values and Defaults + +Services often provide default values for resource fields, and occasionally +normalize the user input before returning it in the response. The guidance +herein describes how services document such behavior for the benefit of +consumers. + +## Guidance + +### Single Owner Fields + +Fields **must** have a single owner, whether that is the client or the server. +Server owned fields **must** be indicated with the `OUTPUT_ONLY` field_behavior. +All other types of fields **must** be considered to be owned by the client. The +server **must** respect the value (or lack thereof) for all client owned fields +and not modify them. + +### Effective Values + +There are instances where a service will allocate, generate, or calculate a +value if the client chooses not to specify one. For example: a client creates a +virtual machine without specifying a static IP address for the virtual machine +to be available on. Such a scenario is opting into dynamic IP address +allocation. + +Some examples of these types of fields are ones that are: + +* generated (UUID) +* allocated (dynamic IP address) +* assigned (most recent software package version) + +An attribute with an effective value ***must*** be expressed as two fields in +the API: + +* a mutable field that can be optionally set by the user and **must not** be +modified by the service +* an `OUTPUT_ONLY` field that records the effective value decided on by the +service + +Example: +```proto +message VirtualMachine { + … + string ip_address = 4; + string effective_ip_address = 5 [ + (google.api.field_behavior) = OUTPUT_ONLY + ]; +} +``` + +#### Naming + +Effective values **must** be named by prefixing `effective_` to the mutable +field's name. + +### User-Specified Fields + +For user-specified fields, the value in response from the service **must** be +the same as provided by the create or update request. For string fields this +means returning the value unchanged, with one exception: + +* When a string field has a data type annotation, a normalized string that + represents the given value **may** be returned. + +### Normalizations + +A field that is normalized by the service **must** be annotated with the +`google.api.field_info` extension. See [AIP-202](aip-202) for guidance on using +this extension The allowed set of normalizations includes the following formats: + +* uuid +* ipv4 +* ipv6 +* email + +Normalizations on fields **must** be described using the `google.api.field_info` +annotation. + +## Rationale + +Server-modified and default values often make it harder to implement +[declarative clients][]. These clients are often unable to +tell when their desired state matches the current state for these fields, as the +rules by which a server may modify and return values are complex, not public, +and not repeatable. + +### Rationale for Single Owner Fields + +When fields do not have a single owner they can cause issues for +[declarative clients][]. These clients may attempt to set +values for fields that are overwritten by server set values, leading to the +client entering an infinite loop to correct the change. + +### Rationale for Naming + +Consistent naming is important for identifying standard behavior across APIs +and fields. Programmatic association between user-specified and effective values +depends on consistent naming. + +### Rationale for Normalizations + +Normalizations are important to allow services to store and return values in a +standard way while communicating to clients what changes are semantically +identical. Normalizing a value on the service side allows the service to accept +a wider range of semantically identical inputs without needing to maintain every +value as a raw string. Surfacing the normalization that is being applied to +clients allows for client side comparison of sent and retrieved values to check +for differences. + +For example, in a resource that accepts an email address on a particular field +a client may specify a given email address in a variety of ways. For the email +`ada@example.com` a client may choose to specify `ADA@example.com`, +`aDa@example.com`, or `AdA@example.com`. These are semantically identical and +*should* all be accepted by the service. The service then may choose to +normalize the email address for storage and retrieval through downcasing or +canonicalization. Importantly, the information surfaced to clients on the +normalization of a field will not describe the normalization algorithm itself, +but instead the comparison method used to accurately compute if two values +should be considered equal. + +### Rationale for Field Value Handling + +For fields not using an allowed normalization, +[Declarative clients][] will not be able to identify which changes are +semantically meaningful. When a [Declarative client][Declarative clients] +sends a particular value it will ensure that the value is being returned by the +service to validate it was set correctly. + +## Changelog + +- **2023-10-31:** Update to approved. + +[Declarative clients]: ./0009.md#declarative-clients +[aip-202]: ./0202.md + + +[aip-180]: ./0180.md + diff --git a/aep/general/0129/aep.yaml b/aep/general/0129/aep.yaml new file mode 100644 index 00000000..654aa485 --- /dev/null +++ b/aep/general/0129/aep.yaml @@ -0,0 +1,7 @@ +--- +id: 129 +state: approved +slug: server-modified-values +created: 2024-07-11 +placement: + category: standard-methods From bbdf57a2fd47ea6d761515ba75021287a116814f Mon Sep 17 00:00:00 2001 From: Tim Burks Date: Thu, 11 Jul 2024 13:01:13 -0700 Subject: [PATCH 2/2] feat(server-modified-values): reset changelog to show import from aip.dev --- aep/general/0129/aep.md.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aep/general/0129/aep.md.j2 b/aep/general/0129/aep.md.j2 index 4f11f6e1..f6ba69a6 100644 --- a/aep/general/0129/aep.md.j2 +++ b/aep/general/0129/aep.md.j2 @@ -128,7 +128,7 @@ service to validate it was set correctly. ## Changelog -- **2023-10-31:** Update to approved. +- **2024-07-11:** Imported from https://google.aip.dev/129 [Declarative clients]: ./0009.md#declarative-clients [aip-202]: ./0202.md