Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(AIP-202): add Type References section #1345

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
20 changes: 20 additions & 0 deletions aip/general/0146.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,28 @@ which is an often-unfamiliar process.
Because of this, `Any` **should not** be used unless other options are
infeasible.

If an `Any` is used it **must** be annotated with the type(s) it references. See
[AIP-202 Type References][typeref] for more details.

## Rationale

### Declaring `Any` type references

At runtime, an `Any` will have the fully-qualified type name in the `type_url`
field to enable the runtime consumer to look up the descriptor and unpack the
message. However, there is no machine-readable indicator in the API
specification itself as to what type(s) could possible be packed in a given
`Any` field. This prevents development of static analysis and runtime compliance
tools, as well as accurate documentation and client library support. As such, an
annotation is necessary to forward declare what an `Any` could contain.

## Changelog

- **2024-08-19:** Add `Any` type reference requirement and rationale.

<!-- prettier-ignore-start -->
[any]: https://github.com/protocolbuffers/protobuf/tree/master/src/google/protobuf/any.proto
[struct]: https://github.com/protocolbuffers/protobuf/tree/master/src/google/protobuf/struct.proto
[JSONSchema]: https://json-schema.org/
[typeref]: ./0202.md#type-references
<!-- prettier-ignore-end -->
55 changes: 55 additions & 0 deletions aip/general/0202.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,39 @@ backwards compatible.
Any new `FieldInfo.Format` value **must** be governed by an
[IETF-approved RFC][ietf rfc] or a [Google-approved AIP](./0001.md).

### Type References

Some generic field types (AIP-146), like `google.protobuf.Any`, can still have
noahdietz marked this conversation as resolved.
Show resolved Hide resolved
a limited set of possible types. Identifying the type(s) of said field can be
done with the `google.api.TypeReference` via the
`google.api.FieldInfo.referenced_types` field, like so:

```proto
message ModelResponse {
google.protobuf.Any raw_response = 1 [(google.api.field_info) = {
referenced_types: {type_name: "google.library.v1.TitleGenerationResponse"}
referenced_types: {type_name: "google.library.v1.ChapterGenerationResponse"}
referenced_types: {type_name: "google.library.v1.SummaryGenerationResponse"}
}];
}
```

If the set of possible types is unknown to the specification author, e.g. the
*client* packs the field with its own type, then a single `referenced_types`
entry with `type_name : "*"` can be used. The wildcard value **must not** be
used in conjunction with fully-qualified references.

Currently, the field annotated with `referenced_types` **must** be of type
`google.protobuf.Any`.

#### Type Reference Compatibility

Adding a new type reference to an existing field is **backwards compatible**, so
long as it matches what the field has always contained.

Changing a type reference in place or removing a possible type is
**not backwards compatible**, and should be considered a breaking change.

## Rationale

#### Why add a format specifier?
Expand Down Expand Up @@ -112,10 +145,32 @@ and see usage in Google APIs. Requiring such extra guidance means that governing
the format specification is not the responsibility of the `FieldInfo.Format`
enumeration itself.

#### Why annotate type reference on generic-typed fields?

Without this statically defined type information, tools consuming the API
specification have no indicator of the types that the generic field could
contain, limiting their ability to facilitate accurate API consumption. See
[AIP-146 Declaring `Any` type references][generics] for more specific rationale.

#### Why support a wildcard value for type references?

There are cases where the set of possible types for a generic field is not known
to the author/service implementor. For example, when a generic is used as part
of a shared interface, like a platform logging framework, or when it is used to
accept generic user input. In these cases, the wildcard value explicitly states
the ambiguous nature of the field to consumers, tools, etc. to be handled
accorindgly. Without it, the alternative is simply not annotating a generic
field, which conveys nothing.

## Changelog

- **2024-08-19:** Add Type References section for new `referenced_types` field.

[field info proto]: https://github.com/googleapis/googleapis/blob/master/google/api/field_info.proto
[rfc 4122]: https://datatracker.ietf.org/doc/html/rfc4122
[rfc 791]: https://datatracker.ietf.org/doc/html/rfc791
[rfc 4291]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.2
[rfc 5952]: https://datatracker.ietf.org/doc/html/rfc5952
[ietf rfc]: https://www.ietf.org/standards/rfcs
[java uuid]: https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html
[generics]: ./0146.md#declaring-any-type-references
Loading