-
Notifications
You must be signed in to change notification settings - Fork 501
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
182 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,182 @@ | ||
--- | ||
id: 185 | ||
state: approved | ||
created: 2024-10-22 | ||
placement: | ||
category: compatibility | ||
order: 40 | ||
--- | ||
|
||
This topic describes the versioning strategies used by Google APIs. In | ||
general, these strategies apply to all Google-managed services. | ||
|
||
## Guidance | ||
|
||
All Google API interfaces **must** provide a _major version number_, which is | ||
encoded at the end of the protobuf package, and included as the first part of | ||
the URI path for REST APIs. In the event an API needs to make an incompatible | ||
change, consult [AIP-180][] and [AIP-181][] for necessary steps based on the | ||
stability level of the surface in question. | ||
|
||
Note: The use of the term "major version number" above is taken from | ||
[semantic versioning][]. However, unlike in traditional semantic versioning, | ||
Google APIs **must not** expose minor or patch version numbers. For | ||
example, Google APIs use `v1`, not `v1.0`, `v1.1`, or `v1.4.2`. From a user's | ||
perspective, major versions are updated in place, and users receive new | ||
functionality without migration. | ||
|
||
A new major version of an API **must not** depend on a previous major version of | ||
the same API. An API surface **must not** depend on other APIs, except for in | ||
the cases outlined in [AIP-213][] and [AIP-215][]. | ||
|
||
Different versions of the same API **must** be able to work at the same time | ||
within a single client application for a reasonable transition period. This time | ||
period allows the client to transition smoothly to the newer version. An older | ||
version **must** go through a reasonable, well-communicated deprecation period | ||
before being shut down. | ||
|
||
For releases which have [alpha or beta stability][AIP-181], APIs **must** append | ||
the stability level after the major version number in the protobuf package and | ||
URI path using one of these strategies: | ||
|
||
- Channel-based versioning (recommended) | ||
- Release-based versioning | ||
- Visibility-based versioning | ||
|
||
### Channel-based versioning | ||
|
||
A *stability channel* is a long-lived release at a given stability level that | ||
receives in-place updates. There is no more than one channel per stability level | ||
for a major version. Under this strategy, there are up to three channels | ||
available: alpha, beta, and stable. | ||
|
||
The alpha and beta channel **must** have their stability level appended to the | ||
version, but the stable channel **must not** have the stability level appended. | ||
For example, `v1` is an acceptable version for the stable channel, but `v1beta` | ||
or `v1alpha` are not. Similarly, `v1beta` or `v1alpha` are acceptable versions | ||
for the respective beta and alpha channel, but `v1` is not acceptable for | ||
either. Each of these channels receives new features and updates "in-place". | ||
|
||
The beta channel's functionality **must** be a superset of the stable channel's | ||
functionality, and the alpha channel's functionality **must** be a superset of | ||
the beta channel's functionality. | ||
|
||
#### Deprecating API functionality | ||
|
||
API elements (fields, messages, RPCs) **may** be marked deprecated in any | ||
channel to indicate that they should no longer be used: | ||
|
||
```proto | ||
// Represents a scroll. Books are preferred over scrolls. | ||
message Scroll { | ||
option deprecated = true; | ||
// ... | ||
} | ||
``` | ||
|
||
Deprecated API functionality **must not** graduate from alpha to beta, nor beta | ||
to stable. In other words, functionality **must not** arrive "pre-deprecated" | ||
in any channel. | ||
|
||
The beta channel's functionality **may** be removed after it has been deprecated | ||
for a sufficient period; we recommend 180 days. For functionality that exists | ||
only in the alpha channel, deprecation is optional, and functionality **may** be | ||
removed without notice. If functionality is deprecated in an API's | ||
alpha channel before removal, the API **should** apply the same annotation, and | ||
**may** use any timeframe it wishes. | ||
|
||
### Release-based versioning | ||
|
||
**Important:** This pattern is not commonly used for new services. There are | ||
existing services that follow it, but Channel-based Versioning is the preferred | ||
mechanism. | ||
|
||
An *individual release* is an alpha or beta release that is expected to be | ||
available for a limited time period before its functionality is incorporated | ||
into the stable channel, after which the individual release will be shut down. | ||
When using release-based versioning strategy, an API may have any number of | ||
individual releases at each stability level. | ||
|
||
Note: Both the channel-based and release-based strategies update the _stable_ | ||
version in-place. There is a single stable channel, rather than individual | ||
stable releases, even when using the release-based strategy. | ||
|
||
Alpha and beta releases **must** have their stability level appended to the | ||
version, followed by an incrementing release number. For example, `v1beta1` or | ||
`v1alpha5`. APIs **should** document the chronological order of these versions | ||
in their documentation (such as comments). | ||
|
||
Each alpha or beta release **may** be updated in place with backwards-compatible | ||
changes. For beta releases, backwards-incompatible updates **should** be made by | ||
incrementing the release number and publishing a new release with the change. | ||
For example, if the current version is `v1beta1`, then `v1beta2` is released | ||
next. | ||
|
||
Alpha and beta releases **should** be shut down after their functionality | ||
reaches the stable channel. An alpha release **may** be shut down at any time, | ||
while a beta release **should** allow users a reasonable transition period; we | ||
recommend 180 days. | ||
|
||
### Visibility-based versioning | ||
|
||
[API visibility][] is an advanced feature provided by Google API infrastructure. | ||
It allows API producers to expose multiple external API views from one internal | ||
API surface, and each view is associated with an API _visibility label_, such | ||
as: | ||
|
||
```proto | ||
import "google/api/visibility.proto"; | ||
message Resource { | ||
string name = 1; | ||
// Preview. Do not use this feature for production. | ||
string display_name = 2 | ||
[(google.api.field_visibility).restriction = "PREVIEW"]; | ||
} | ||
``` | ||
|
||
A visibility label is a case-sensitive string that can be used to tag any API | ||
element. By convention, visibility labels should always use UPPER case. | ||
An implicit `PUBLIC` label is applied to all API elements unless an explicit | ||
visibility label is applied as in the example above. | ||
|
||
Each visibility label is an allow-list. API producers need to grant visibility | ||
labels to API consumers for them to use API features associated with the labels. | ||
In other words, an API visibility label is like an ACL'ed API version. | ||
|
||
Multiple visibility labels **may** be applied to an element by using a | ||
comma-separated string (e.g. `"PREVIEW,TRUSTED_TESTER"`). When multiple | ||
visibility labels are used, then the client needs only _one_ of the visibility | ||
labels (logical `OR`). | ||
|
||
By default, the visibility labels granted to the API consumer are used to verify | ||
incoming requests. However, a client can send requests with an explicit | ||
visibility label as follows: | ||
|
||
``` | ||
GET /v1/projects/my-project/topics HTTP/1.1 | ||
Host: pubsub.googleapis.com | ||
Authorization: Bearer y29.... | ||
X-Goog-Visibilities: PREVIEW | ||
``` | ||
|
||
A single API request can specify at most one visibility label. | ||
|
||
API producers can use API visibility for API versioning, such as | ||
`INTERNAL` and `PREVIEW`. A new API feature starts with the `INTERNAL` label, | ||
then moves to the `PREVIEW` label. When the feature is stable and becomes | ||
generally available, all API visibility labels are removed from the API | ||
definition. | ||
|
||
In general, API visibility is easier to implement than API versioning for | ||
incremental changes, but it depends on sophisticated API infrastructure support. | ||
Google Cloud APIs often use API visibility for Preview features. | ||
|
||
[AIP-180]: https://aip.dev/180 | ||
[AIP-181]: https://aip.dev/181 | ||
[AIP-213]: https://aip.dev/213 | ||
[AIP-215]: https://aip.dev/215 | ||
[api visibility]: https://github.com/googleapis/googleapis/blob/master/google/api/visibility.proto | ||
[semantic versioning]: https://semver.org/ |