Skip to content

Commit febea74

Browse files
feat: AIP-213 – Common components (#100)
* Import google.aip.dev's AIP-213, without modifications. * Genericize Google's AIP-213 and substantially rework it. Also specifically proposes the following: * An AIP type repo at github.com/aip/type, which defines both protos and JSON Schemas. * Publishing the JSON Schemas to schemastore.org. * Publishing the protos via the Buf Schema Repository (buf.build). * Clarify that all types will have READMEs but may not all have defined schemas. * Linkify list of existing common components. * Make some changes based on discussion with jjg@: * Mention libraries for common types. * Add carve-out for extending common components (to allow e.g. google.type). * Rename the aip-dev/type repo to aip-dev/common-components. * Update aip/general/0213/aip.md Co-authored-by: Yusuke Tsutsumi <[email protected]> * Update aip/general/0213/aip.md Co-authored-by: Yusuke Tsutsumi <[email protected]> * Clarify use case section * Drop section on extending common components. * Group types in a section and add a note saying the list is not exhaustive. * Clarify appropriate use of Value and Struct * Move all link definitions to bottom of file * Tweak wording to remove we * More voice/phrasing tweaks * Remove redundant call to action. --------- Co-authored-by: Yusuke Tsutsumi <[email protected]>
1 parent bb610fd commit febea74

File tree

2 files changed

+209
-0
lines changed

2 files changed

+209
-0
lines changed

aip/general/0213/aip.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Common components
2+
3+
In general, APIs should be designed to be self-contained. APIs generally need
4+
to be able to move forward independently of one another, and mutual
5+
dependencies can cause downstream APIs to be forced into taking major version
6+
changes or even lead to dependency conflicts.
7+
8+
However, there are also cases where common structures are valuable, especially
9+
where a concept is well-known and it is sufficiently clear that it will not
10+
change. Having a single representation of these common structures is valuable
11+
because it avoids disrepancies between APIs in things like how dates or
12+
monetary values are represented. It also enables shared libraries for common
13+
operations, such as basic arithmetic on monetary values.
14+
15+
Common components serve this use case.
16+
17+
## Guidance
18+
19+
The public representation of APIs **should** be self-contained (for protocol
20+
buffers, this means that all API protos used by the API originate in the same
21+
proto `package`), except for common components, which **may** be used freely in
22+
any API.
23+
24+
An API **must not** define a set of API-specific common components which live
25+
outside of its versioning structure. This prevents independent movement of
26+
particular versions and also causes problems for client libraries in many
27+
languages that compile protobuf messages into classes.
28+
29+
An API **should not** define alternative representations of any of the existing
30+
common components described below, even within its versioning structure.
31+
32+
## Existing common components
33+
34+
The common components, which public-facing APIs **may** safely depend on, are
35+
defined canonically in the [AIP common components][] repository. These include
36+
READMEs with canonical definitions for each component, and -- when applicable
37+
-- implementations of these definitions, in both JSON Schema and protobuf
38+
formats. The protobufs are also published to the Buf Schema Sepository at
39+
[`buf.build/aip/common`][buf], and the JSON schemas are published to the [JSON
40+
Schema Store][] with names beginning with `aip-`, for example `aip-type-money`
41+
or `aip-longrunning-operation`.
42+
43+
While the [AIP common components][] repository is canonical and takes
44+
precedence over this list, some of the common components defined there include
45+
representations of the following concepts:
46+
47+
### API design patterns
48+
49+
- `StatusMonitor` / `Operation`: Represents the status of a long-running
50+
request (see [AIP-151][] for details).
51+
52+
#### gRPC-specific API design patterns
53+
54+
- [`google.api.*`][api] (but _not_ subpackages of `google.api`): Annotations
55+
useful for gRPC/JSON transcoding, supported by frameworks including .NET 7.
56+
57+
- [`google.rpc.*`][rpc]: A small number of components related to gRPC
58+
request/response status and errors.
59+
60+
### Common types
61+
62+
This section provides examples for the sake of illustration; it may not be
63+
exhaustive. The [AIP common components][] repo is canonical.
64+
65+
#### General common types
66+
67+
- [`Color`][color]: RGB or RGBA colors.
68+
69+
- [`Fraction`][fraction]: A numeric fraction.
70+
71+
- [`LatLng`][lat_lng]: Geographic coordinates.
72+
73+
- [`Money`][money]: An amount of money in a given currency.
74+
75+
- [`PhoneNumber`][phone_number]: A phone number in most countries.
76+
77+
- [`PostalAddress`][postal_address]: Postal addresses in most countries.
78+
79+
- [`Quaternion`][quaternion]: A geometric quaternion.
80+
81+
#### Date- and time-related types
82+
83+
- [`Date`][date]: A calendar date, with no time or time zone component.
84+
85+
- [`DateTime`][date_time]: A calendar date and wall-clock time, with optional
86+
time zone or UTC offset information.
87+
88+
- [`DayOfWeek`][day_of_week]: An enumeration representing the day of the week.
89+
90+
- [`Duration`][duration]: A duration with nanosecond-level precision.
91+
92+
- [`Interval`][interval]: An interval between two timestamps.
93+
94+
- [`Month`][month]: An enumeration representing the Gregorian month.
95+
96+
- [`TimeOfDay`][time_of_day]: Wall-clock time, with no date or time zone
97+
component.
98+
99+
- [`Timestamp`][timestamp]: A timestamp with nanosecond-level precision.
100+
101+
#### Protobuf types
102+
103+
The [`google.protobuf`][protobuf] package is shipped with protocol buffers
104+
itself, rather than with API tooling. The Well-Known Types defined in this
105+
package should always be used when appropriate, and the [AIP common
106+
components][] repo does not define any protos for these types, even when it
107+
defines a corresponding JSON Schema. These include:
108+
109+
- [`google.protobuf.Duration`][duration]: Durations, with nanosecond-level
110+
precision. The protobuf runtime provides helper functions to convert to and
111+
from language-native duration objects where applicable (such as Python's
112+
[`timedelta`][timedelta]).
113+
- [`google.protobuf.Timestamp`][timestamp]: Timestamps, with nanosecond-level
114+
precision. The protobuf runtime provides helper functions in most languages
115+
to convert to and from language-native timestamp objects (such as Python's
116+
[`datetime`][datetime]).
117+
118+
`google.protobuf` also provides some useful components that correspond to JSON
119+
primitives (and so have no representation at all in the [AIP common
120+
components][] repo), namely:
121+
122+
- [`google.protobuf.Value`][struct]: An arbitrary JSON value. The protobuf
123+
runtime provides helper functions in most languages to convert `Value`
124+
objects to and from JSON.
125+
- [`google.protobuf.Struct`][struct]: JSON-like structures (a dictionary of
126+
primitives, lists, and other dictionaries). The protobuf runtime provides
127+
helper functions in most languages to convert `Struct` objects to and from
128+
JSON.
129+
130+
`google.protobuf.Struct` and `google.protobuf.Value` are designated common
131+
components by this AIP; proto-based APIs **should** use them when representing
132+
arbitrary JSON-like structures.
133+
134+
## Libraries for common types
135+
136+
For the common components in the `aip.type` namespace, which represent common
137+
data types, the [AIP common components][] repo may contain canonical libraries
138+
in a number of languages. These libraries are designed to be idiomatic in a
139+
given language, and should feel similar to using the language's standard
140+
libraries. They should provide basic functionality like adding two `Money`
141+
values, or determining if one `Date` comes before another.
142+
143+
When a language already has a standard library representation of a common type
144+
(such as Python's `datetime` for the `Timestamp` type), there may instead be a
145+
library for converting the JSON or protobuf representation to the standard
146+
library representation.
147+
148+
If a library you want does not exist, and you want to contribute one, please
149+
[open an issue][] on the [AIP common components][] repository in GitHub.
150+
151+
## Appendix: Adding to common components
152+
153+
Occasionally, it may be useful to add protos to these packages or to add to the
154+
list of common components. In order to do this, [open an issue][] on the [AIP
155+
common components][] repository in GitHub.
156+
157+
However, some general guidelines are worth noting for this:
158+
159+
- Schemas **should** only be granted common component status if it is certain
160+
that they will never change (at all -- even in ways that would normally be
161+
considered backwards compatible). Common components are not versioned, and it
162+
must be the case that API creators and consumers can rely on the component to
163+
be a complete and accurate representation indefinitely.
164+
- Schemas must be applicable to a significant number of APIs for consideration
165+
as common components.
166+
- Even after a common component is added, APIs using local versions **must**
167+
continue to do so until they go to the next major version.
168+
169+
<!-- prettier-ignore-start -->
170+
[api]: https://github.com/googleapis/googleapis/tree/master/google/api
171+
[rpc]: https://github.com/googleapis/googleapis/tree/master/google/rpc
172+
173+
[color]: https://github.com/aip-dev/common-components/tree/master/aip/type/color
174+
[fraction]: https://github.com/aip-dev/common-components/tree/master/aip/type/fraction
175+
[lat_lng]: https://github.com/aip-dev/common-components/tree/master/aip/type/lat_lng
176+
[money]: https://github.com/aip-dev/common-components/tree/master/aip/type/money
177+
[phone_number]: https://github.com/aip-dev/common-components/tree/master/aip/type/phone_number
178+
[postal_address]: https://github.com/aip-dev/common-components/tree/master/aip/type/postal_address
179+
[quaternion]: https://github.com/aip-dev/common-components/tree/master/aip/type/quaternion
180+
181+
[date]: https://github.com/aip-dev/common-components/tree/master/aip/type/date
182+
[date_time]: https://github.com/aip-dev/common-components/tree/master/aip/type/date_time
183+
[day_of_week]: https://github.com/aip-dev/common-components/tree/master/aip/type/day_of_week
184+
[duration]: https://github.com/aip-dev/common-components/tree/master/aip/type/duration
185+
[interval]: https://github.com/aip-dev/common-components/tree/master/aip/type/interval
186+
[month]: https://github.com/aip-dev/common-components/tree/master/aip/type/month
187+
[time_of_day]: https://github.com/aip-dev/common-components/tree/master/aip/type/time_of_day
188+
[timestamp]: https://github.com/aip-dev/common-components/tree/master/aip/type/timestamp
189+
190+
[datetime]: https://docs.python.org/3/library/datetime.html#datetime.datetime
191+
[duration]: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/duration.proto
192+
[protobuf]: https://github.com/protocolbuffers/protobuf/tree/main/src/google/protobuf
193+
[struct]: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto
194+
[timedelta]: https://docs.python.org/3/library/datetime.html#datetime.timedelta
195+
[timestamp]: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto
196+
197+
[open an issue]: https://github.com/aip-dev/common-components/issues
198+
[aip common components]: https://github.com/aip-dev/common-components
199+
[json schema store]: https://www.schemastore.org/json/
200+
[aip-151]: ../0151
201+
[buf]: https://buf.build/aip/type
202+
<!-- prettier-ignore-end -->

aip/general/0213/aip.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
id: 213
3+
state: draft
4+
created: 2022-09-13
5+
placement:
6+
category: resource-design
7+
order: 120

0 commit comments

Comments
 (0)