diff --git a/aip/general/0203.md b/aip/general/0203.md index 7de5e39f2..03a7a094f 100644 --- a/aip/general/0203.md +++ b/aip/general/0203.md @@ -42,7 +42,7 @@ backwards-compatility. Nontheless, this annotation **must not** be omitted. only, and does not itself add any validation. The purpose is to consistently document this behavior for clients. -### field behavior of nested messages +### Field behavior of nested messages `google.api.field_behavior` annotations on a nested message are independent of the annotations of the parent. @@ -62,6 +62,38 @@ message Slide { In the case above, if a `title` is specified, the `text` field is required. +If a field containing a nested message is annotated as `OUTPUT_ONLY`, +all of the nested message fields **must** also be annotated as `OUTPUT_ONLY`. + +For example, the following is incorrect as `text` is a required field: + +```proto +message Title { + string text = 1 [(google.api.field_behavior) = REQUIRED]; +} + +message Slide { + // Incorrect. Title defines `text` as a required field. + Title title = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; +} +``` + +The following is correct, as `reverse` is a leaf field and does not +override behavior. If `Slide.title` is specified, `text` must be provided, +and `reverse` will be computed by the service and returned in responses: + +```proto +message Title { + string text = 1 [(google.api.field_behavior) = REQUIRED]; + + string reverse = 2 [(google.api.field_behavior) = OUTPUT_ONLY]; +} + +message Slide { + Title title = 1 [(google.api.field_behavior) = OPTIONAL]; +} +``` + ## Vocabulary ### Identifier @@ -264,6 +296,19 @@ RPC or a resource in a [Declarative client][]. See the [Backwards compatibility](#backwards-compatibility) section for more detailed compatibility guidance. +### Field behavior of nested messages + +Nested messages allow avoiding code duplication, where the same type can be shared +by multiple messages. Given that field behavior annotations are also required for +nested messages, field behavior must also implicitly be shared. Annotating a field +with `OUTPUT_ONLY`, when the field is a sub-message declaring `REQUIRED` and/or +`OPTIONAL` fields, forces clients to treat this sub-message differently depending +on the context it is used in. Forcing services to consistently separate output +fields from user-defined fields avoids this problem. Additionally, there is little +value in annotating sub-fields of `OUTPUT_ONLY` fields as either `REQUIRED` or +`OPTIONAL`, since the consequences of breaking this contract by services still +have to be handled by clients. + ## History In 2023-05 field_behavior was made mandatory. Prior to this change, the @@ -285,6 +330,8 @@ surpass the costs to clients and API users of not doing so. ## Changelog +- **2023-11-27**: Clarify that overriding behavior through nesting is only +- supported for REQUIRED and OPTIONAL. - **2023-09-14**: Clarify that nested behavior and parent behavior are independent. - **2023-08-25**: Add guidance on `IDENTIFIER`.