-
Notifications
You must be signed in to change notification settings - Fork 510
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
120 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
--- | ||
id: 202 | ||
state: reviewing | ||
created: 2023-09-22 | ||
placement: | ||
category: fields | ||
order: 0 | ||
--- | ||
|
||
# Fields | ||
|
||
The [`google.api.Field`][field proto] type, through its accompanying extension | ||
`google.api.field`, enriches a field's schema beyond the basic name and type | ||
information. | ||
|
||
## Guidance | ||
|
||
Decorating a field with `google.api.field` is only necessary when explicitly | ||
stated in this AIP or another that leverages `google.api.Field` information. As | ||
such, the guidance herein applies to those scenarios as well. | ||
|
||
### Format | ||
|
||
Fields with a primitive type can still have a specific format. To convey that | ||
type format, the `Field.Format` enumeration is used via the | ||
`(google.api.field).format` extension field. The following guidance conveys the | ||
meaning of and requirements for use of each `Field.Format` value. | ||
|
||
#### UUID4 | ||
|
||
The `UUID4` format represents a UUID version 4 value as governed by | ||
[RFC 4122][]. It **must** only be used on a field of type `string`. | ||
|
||
Such a value **may** be normalized by the service to entirely lowercase letters. | ||
For example, the value `F47AC10B-58CC-0372-8567-0E02B2C3D479` would be | ||
normalized to `f47ac10b-58cc-0372-8567-0e02b2c3d479`. | ||
|
||
As such, equivalence comparison **must not** be done via primitive text | ||
comparison. Instead, an [RFC 4122][] compliant implementation **must** be used. | ||
|
||
#### IPv4 | ||
|
||
The `IPV4` format represents an IP v4 address as governed by [RFC 791][]. It | ||
**must** only be used on a field of type `string`. | ||
|
||
Such a value **may** be condensed by the service, with leading zeros in each | ||
octet stripped. For example, `001.022.233.040` would be condensed to | ||
`1.22.233.40`. | ||
|
||
As such, equivalence comparison **must not** be done via primitive text | ||
comparison. Instead, an [RFC 791][] compliant implementation **must** be used. | ||
|
||
#### IPv6 | ||
|
||
The `IPV6` format represents an IP v6 address as governed by [RFC 4291][]. It | ||
**must** only be used on a field of type `string`. | ||
|
||
Such a value **may** be normalized by the service to entirely lowercase letters, | ||
and zero-padded partial and empty octets. For example, the value `2001:DB8::` | ||
would be normalized to `2001:0db8:0:0`. | ||
|
||
As such, equivalence comparison **must not** be done via primitive text | ||
comparison. Instead, an [RFC 4291][] compliant implementation **must** be used. | ||
|
||
#### IPv4 or IPv6 | ||
|
||
The `IPV4_OR_IPV6` value indicates that the field can be either an IP v4 or v6 | ||
address, as described in the [IPv4](#ipv4) and [IPv6](#ipv6) sections. | ||
|
||
#### Format Compatibility | ||
|
||
Adding a format specifier to an existing, unspecified field **is not** backwards | ||
compatible, *unless* the field in question has always conformed to the format | ||
being specified. | ||
|
||
Changing an existing format specifier to a different one in all cases **is not** | ||
backwards compatible. | ||
|
||
#### Extending Format | ||
|
||
Any new `Field.Format` value **must** be governed by an | ||
[IETF-approved RFC][ietf rfc] or a [Google-approved AIP](./0001.md). | ||
|
||
## Rationale | ||
|
||
#### Why add a format specifier? | ||
|
||
The format of a primitive-typed field can be critical to its usability. Some | ||
programming languages may convey a specific type format as a standalone type, | ||
as Java does with [UUID][java uuid]. Most have specific structural requirements | ||
that are validated by the service, so conveying the format to the user ahead of | ||
time is critical to their experience. | ||
|
||
#### Why discourage primitive equality comparisons? | ||
|
||
The text representations of the supported formats have many nuances and | ||
transforming the value into a canonical representation is non-trivial. As such, | ||
aligning implementations between each consumer and each service without any | ||
issue is infeasiable. | ||
|
||
#### Why document value normalizations? | ||
|
||
While primitive comparison is not recommended for any of the supported formats, | ||
uniform normalization of values is important to set consumer expectations, and | ||
create a user-friendly surface. | ||
|
||
#### Why require an RFC or AIP for new formats? | ||
|
||
Those formats which are sufficiently standardized to merit an RFC or AIP are | ||
stable enough and widely enough known to be incorporated as a supported value | ||
and see usage in Google APIs. Requiring such extra guidance means that governing | ||
the format specification is not the responsibility of the `Field.Format` | ||
enumeration itself. | ||
|
||
[field proto]: https://github.com/googleapis/googleapis/blob/master/google/api/field.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 | ||
[ietf rfc]: https://www.ietf.org/standards/rfcs | ||
[java uuid]: https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html |