From 8a23a9b007f91b2fe3d4124df446aa4fb13e3666 Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 3 Oct 2025 11:14:15 -0700 Subject: [PATCH 1/9] feat(AIP-180): add string length change guidance --- aip/general/0180.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/aip/general/0180.md b/aip/general/0180.md index 2bcad7f977..6500831f33 100644 --- a/aip/general/0180.md +++ b/aip/general/0180.md @@ -64,6 +64,11 @@ However, keep the following guidelines in mind when doing this: resources. - Any field being populated by clients **must** have a default behavior matching the behavior before the field was introduced. + - This can be tricky to do in some case. For example, adding pagination + after the fact where previously all items were returned (i.e. `page_size` + is infinite, which is not advised). If the default for the new `page_size` + field is _less_ than what was previously returned, older clients will + incorrectly assume all results were returned. - Any field previously populated by the server **must** continue to be populated, even if it introduces redundancy. - For enum values specifically, be aware that it is possible that user code @@ -113,6 +118,15 @@ Existing fields and messages **must not** have their type changed, even if the new type is wire-compatible, because type changes alter generated code in a breaking way. +### Changing string length + +APIs **should** forward declare the upper bound of expected size and/or the +limit (if accepted as input) in field documentation. APIs **should** avoid +changing this and **should** treat expected size upper bound increases as +incompatible changes (see [Changing resource names](#changing-resource-names) as +an example). APIs **may** pad out values with filler characters if reserving a +consistent size is necessary, but this **must** be documented if done. + ### Changing resource names A resource **must not** change its [name][aip-122]. @@ -245,8 +259,21 @@ version. - For compatibility around field presence changes, see [AIP-149][]. - For compatibility around resource types, see [AIP-123][]. +## Rationale + +### Risk of string length changes + +End users may store resource properties, like the `name`, in a dedicated +database column with a limited length. If the service starts returning values +for the `name` that are twice the originally documented/observed length, this +may unexpectedly break the customer's database. Furthermore, string properties +that appear in URLs (incl. query parameters) are especially likely to have +client-side limits, making them more sensitive to length changes. + ## Changelog +- **2025-10-03**: Added guidance for string length changes and an example for + carefully adding components. - **2024-08-07**: Added reference to resource type compatibility. - **2024-06-05**: Added reference to field presence compatibility. - **2023-07-26**: Added reference to field behavior compatibility. From 36253ebf30742d940ef1db15fb7d09d837adcd6e Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 3 Oct 2025 11:14:34 -0700 Subject: [PATCH 2/9] fix(AIP-126): allow UNKNOWN to be prefixed --- aip/general/0126.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/aip/general/0126.md b/aip/general/0126.md index ee89943610..85f10cda29 100644 --- a/aip/general/0126.md +++ b/aip/general/0126.md @@ -54,7 +54,9 @@ message Book { followed by the suffix `_UNSPECIFIED`. - An exception to this rule is if there is a clearly useful zero value. In particular, if an enum needs to present an `UNKNOWN`, it is usually clearer - and more useful for it to be a zero value rather than having both. + and more useful for it to be a zero value rather than having both. The + `UNKNOWN` value **may** be prefixed by the enum name as is typical for + avoiding enum value name collisions. - Enums which will only be used in a single message **should** be nested within that message. In this case, the enum **should** be declared immediately before it is used. - The non-zero values of such a nested enum definition **should not** be prefixed by the name @@ -113,3 +115,7 @@ choice (although `google.protobuf.BoolValue` is also available). [aip-216]: ./0216.md [bcp-47]: https://en.wikipedia.org/wiki/IETF_language_tag [media types]: https://en.wikipedia.org/wiki/Media_type + +## Changelog + +- **2025-10-03**: Added prefixing guidance for `UNKNOWN` value exception. From 5e58372408a7e440d439c95d2576a2a89e7c986a Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 3 Oct 2025 11:16:39 -0700 Subject: [PATCH 3/9] feat(AIP-157): allow View use in other methods --- aip/general/0133.md | 4 +++- aip/general/0134.md | 4 +++- aip/general/0157.md | 18 +++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/aip/general/0133.md b/aip/general/0133.md index fa5b0f6e9a..f834855840 100644 --- a/aip/general/0133.md +++ b/aip/general/0133.md @@ -43,7 +43,8 @@ rpc CreateBook(CreateBookRequest) returns (Book) { `CreateBookResponse`. - The response **should** include the fully-populated resource, and **must** include any fields that were provided unless they are input only (see - [AIP-203][]). + [AIP-203][]) or there is a reason to return a partial response (see + [AIP-157][]). - If the create RPC is [long-running](#long-running-create), the response message **must** be a `google.longrunning.Operation` which resolves to the resource itself. @@ -219,6 +220,7 @@ name and use it in references from other resources. ## Changelog +- **2025-10-03**: Allow use of partial responses via AIP-157. - **2023-10-20**: Clarify that {resource}_id is only required for management plane resources. - **2023-08-24**: Adding consistency requirement. - **2023-05-11**: Changing guidance around resource_id to a must. diff --git a/aip/general/0134.md b/aip/general/0134.md index e61bedc838..a42910c090 100644 --- a/aip/general/0134.md +++ b/aip/general/0134.md @@ -43,7 +43,8 @@ rpc UpdateBook(UpdateBookRequest) returns (Book) { `UpdateBookResponse`.) - The response **should** include the fully-populated resource, and **must** include any fields that were sent and included in the update mask unless - they are input only (see AIP-203). + they are input only (see AIP-203) or there is a reason to return a partial + response (see [AIP-157][]). - If the update RPC is [long-running](#long-running-update), the response message **must** be a `google.longrunning.Operation` which resolves to the resource itself. @@ -302,6 +303,7 @@ does not exist, the service **must** error with `NOT_FOUND` (HTTP 404) unless ## Changelog +- **2025-10-03**: Allow use of partial responses via AIP-157. - **2024-12-03**: Add caveats to usage of full replacement `update_mask`. - **2024-03-14**: Make `update_mask` optional field_behaviour guidance a **must**. - **2023-08-26**: Adding consistency requirement. diff --git a/aip/general/0157.md b/aip/general/0157.md index aa52f3ac51..15a65e845e 100644 --- a/aip/general/0157.md +++ b/aip/general/0157.md @@ -61,10 +61,15 @@ enum BookView { - The enum **should** at minimum have values named `BASIC` and `FULL` (although it **may** have values other than these). - The `UNSPECIFIED` value **must** be valid (not an error), and the API - **must** document what the unspecified value will do). + **must** document what the unspecified value will do. - For List RPCs, the effective default value **should** be `BASIC`. - - For Get RPCs, the effective default value **should** be either `BASIC` or - `FULL`. + - For the following RPC types, the effective default value **should** be + either `BASIC` or `FULL`: + - Get + - Create + - Update + - Soft Delete + - Custom Method - The enum **should** be defined at the top level of the proto file (as it is likely to be needed in multiple requests, e.g. both `Get` and `List`). See [AIP-126][] for more guidance on top-level enumerations. @@ -76,6 +81,11 @@ enum BookView { conflict. In this situation, the service **should** nest the view enum within the individual resource. + **Note:** Having a partial response be the default of standard methods can + degrade the effectiveness of declarative clients. Providing a mechanism to + request the full resource be populated in the response, like this View + pattern, is preferred if partial responses are deemed necessary. + ### Read masks as a request field **Warning:** Read mask as a single, explicit field on the request message is @@ -107,6 +117,8 @@ potential point of conflict for the client or service. ## Changelog +- **2025-10-03**: Added default view guidance for other RPC types, and + declarative client warning. - **2025-06-16**: Reinstate read mask guidance as historical/external reference. - **2023-05-09**: Fix top-level enum example and link to AIP-126. - **2022-03-14:** Updated guidance on default value and how to specify a read mask. From a7f8c714a6375cd5d95defa3ac31d2b4f4676e0e Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 3 Oct 2025 11:17:02 -0700 Subject: [PATCH 4/9] fix(AIP-160): clarify top-level field HAS behavior --- aip/general/0160.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/aip/general/0160.md b/aip/general/0160.md index 5325645d64..e6caf55a95 100644 --- a/aip/general/0160.md +++ b/aip/general/0160.md @@ -183,6 +183,15 @@ There are two slight distinctions when parsing messages: implementations **may** choose to support automatic conversion between camel case and snake case. +For all aforementioned types, simply checking for the presence of a top-level +resource field is possible with the `*` value: + +| Example | Meaning | +| ---------- | ---------------------------------------- | +| `r:*` | True if `repeated` field `r` is present. | +| `p:*` | True if `map` field `p` is present. | +| `m:*` | True if `message` field `m` is present. | + ### Functions The filtering language supports a function call syntax in order to support @@ -231,5 +240,6 @@ Schematic validation refers, but is not limited to, the following: ## Changelog +- **2025-10-03**: Clarify top-level field has operator behavior. - **2025-01-07**: Clarify behavior for unset field in traversal operator chain. - **2024-12-11**: Move non-compliant filter guidance to Validation section. From 8d69185615c64d5294681b7a99e573266bf93011 Mon Sep 17 00:00:00 2001 From: noahdietz Date: Thu, 9 Oct 2025 09:37:43 -0700 Subject: [PATCH 5/9] feat(AIP-180): add format change guidance --- aip/general/0180.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/aip/general/0180.md b/aip/general/0180.md index 6500831f33..7b421ffce0 100644 --- a/aip/general/0180.md +++ b/aip/general/0180.md @@ -160,6 +160,15 @@ code, as such changes will be seen as breaking by those users. whether a proposed change is likely to break users, and an expansive reading of this guidance could ostensibly prevent _any_ change (which is not the intent). +#### Changing value format or construction + +APIs **must not** change the expected format or algorithm used to construct the +value of an existing field - even if the field is `OUTPUT_ONLY` and populated by +the API service - within an API version. Doing so requires a new API version. + +For example, changing the format of a field `ip_address` conforming to IPv4 +format to instead contain IPv6 values is a breaking change. + #### Default values must not change Default values are the values set by servers for resources when they are not @@ -270,10 +279,16 @@ may unexpectedly break the customer's database. Furthermore, string properties that appear in URLs (incl. query parameters) are especially likely to have client-side limits, making them more sensitive to length changes. +### Risk of changing value format or construction + +Customers often depend on the format or algorithmic construction of a field for +client-side parsing, hashing, or database table construction. Changing it in +an existing field could break that client-side consumption. + ## Changelog -- **2025-10-03**: Added guidance for string length changes and an example for - carefully adding components. +- **2025-10-03**: Added guidance for string length changes, changing formats, + and an example for carefully adding components. - **2024-08-07**: Added reference to resource type compatibility. - **2024-06-05**: Added reference to field presence compatibility. - **2023-07-26**: Added reference to field behavior compatibility. From 648dcf42cdee5d7f854c50c5eaaac9ac940cb703 Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 10 Oct 2025 08:45:09 -0700 Subject: [PATCH 6/9] address feedback on aip-180 --- aip/general/0180.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/aip/general/0180.md b/aip/general/0180.md index 7b421ffce0..3a11fd7fcb 100644 --- a/aip/general/0180.md +++ b/aip/general/0180.md @@ -64,7 +64,7 @@ However, keep the following guidelines in mind when doing this: resources. - Any field being populated by clients **must** have a default behavior matching the behavior before the field was introduced. - - This can be tricky to do in some case. For example, adding pagination + - This can be tricky to do in some cases. For example, adding pagination after the fact where previously all items were returned (i.e. `page_size` is infinite, which is not advised). If the default for the new `page_size` field is _less_ than what was previously returned, older clients will @@ -120,13 +120,17 @@ breaking way. ### Changing string length -APIs **should** forward declare the upper bound of expected size and/or the -limit (if accepted as input) in field documentation. APIs **should** avoid -changing this and **should** treat expected size upper bound increases as -incompatible changes (see [Changing resource names](#changing-resource-names) as -an example). APIs **may** pad out values with filler characters if reserving a +APIs **should** avoid increasing the upper bound for the size or limit (if +accepted as input) of `string` fields. APIs **should** treat expected size upper +bound increases as incompatible changes (see [Changing resource names] +(#changing-resource-names) as an example). APIs **may** forward declare the +upper bound of expected size and/or the limit (if accepted as input) in field +documentation. APIs **may** pad out values with filler characters if reserving a consistent size is necessary, but this **must** be documented if done. +APIs **should** forward declare the upper bound of expected size and/or the +limit (if accepted as input) in field documentation. + ### Changing resource names A resource **must not** change its [name][aip-122]. @@ -276,7 +280,7 @@ End users may store resource properties, like the `name`, in a dedicated database column with a limited length. If the service starts returning values for the `name` that are twice the originally documented/observed length, this may unexpectedly break the customer's database. Furthermore, string properties -that appear in URLs (incl. query parameters) are especially likely to have +that appear in URLs (including query parameters) are especially likely to have client-side limits, making them more sensitive to length changes. ### Risk of changing value format or construction From a90a01f2403714c6f75ec31f6504acc9ed35edc1 Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 10 Oct 2025 08:50:15 -0700 Subject: [PATCH 7/9] address feedback on aip-160 --- aip/general/0160.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aip/general/0160.md b/aip/general/0160.md index e6caf55a95..3a6a7ee18f 100644 --- a/aip/general/0160.md +++ b/aip/general/0160.md @@ -192,6 +192,10 @@ resource field is possible with the `*` value: | `p:*` | True if `map` field `p` is present. | | `m:*` | True if `message` field `m` is present. | +**Note:** For `map` and `repeated` fields, there is no semantic difference +between an unset field and "set with empty value" - they both resolve to "not +present". + ### Functions The filtering language supports a function call syntax in order to support From 60df5fc3264c68f09080636830267880674ca0d3 Mon Sep 17 00:00:00 2001 From: noahdietz Date: Fri, 10 Oct 2025 08:51:40 -0700 Subject: [PATCH 8/9] remove extra line in aip-180 --- aip/general/0180.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/aip/general/0180.md b/aip/general/0180.md index 3a11fd7fcb..806e6ec6c8 100644 --- a/aip/general/0180.md +++ b/aip/general/0180.md @@ -128,9 +128,6 @@ upper bound of expected size and/or the limit (if accepted as input) in field documentation. APIs **may** pad out values with filler characters if reserving a consistent size is necessary, but this **must** be documented if done. -APIs **should** forward declare the upper bound of expected size and/or the -limit (if accepted as input) in field documentation. - ### Changing resource names A resource **must not** change its [name][aip-122]. From 6a712150722cc62fa32c76011cbca789dfa31944 Mon Sep 17 00:00:00 2001 From: noahdietz Date: Tue, 21 Oct 2025 10:10:54 -0700 Subject: [PATCH 9/9] remove string size comment guidance --- aip/general/0180.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/aip/general/0180.md b/aip/general/0180.md index 806e6ec6c8..31af4a6ce7 100644 --- a/aip/general/0180.md +++ b/aip/general/0180.md @@ -123,10 +123,9 @@ breaking way. APIs **should** avoid increasing the upper bound for the size or limit (if accepted as input) of `string` fields. APIs **should** treat expected size upper bound increases as incompatible changes (see [Changing resource names] -(#changing-resource-names) as an example). APIs **may** forward declare the -upper bound of expected size and/or the limit (if accepted as input) in field -documentation. APIs **may** pad out values with filler characters if reserving a -consistent size is necessary, but this **must** be documented if done. +(#changing-resource-names) as an example). APIs **may** pad out values with +filler characters if reserving a consistent size is necessary, but this **must** +be documented if done. ### Changing resource names @@ -288,7 +287,7 @@ an existing field could break that client-side consumption. ## Changelog -- **2025-10-03**: Added guidance for string length changes, changing formats, +- **2025-10-21**: Added guidance for string length changes, changing formats, and an example for carefully adding components. - **2024-08-07**: Added reference to resource type compatibility. - **2024-06-05**: Added reference to field presence compatibility.