AIP-215

Common component versions

Many APIs may support more than one version at the same time. Often, our first instinct is to create protos which are intended to be shared between API versions, and place them in an unversioned “common” directory. A similar variant to this is an omitted version: a message or service that is implicitly v1, but has no version in the proto package.

When protos are unversioned, changing them safely (that is, in a backwards compatible way) is very difficult. For example, adding a field to an unversioned proto effectively adds the field to all existing versions, which do not actually support it. This is surprising to users, and creates a situation where the proto files are not accurate representations of the API surface.

Additionally, client library generators usually generate a class for each message in your protos in a language-appropriate namespace. In several languages, each version of your API is shipped as a separate client library, and the code generator needs to generate the common messages for your API in order to ensure a complete package. This makes it difficult to use multiple APIs with similar dependent messages together.

For omitted versions, the version is effectively hidden, and it becomes more difficult to reason about release phases (alpha, beta, GA), with no substantive benefit.

Guidance

  • All protos specific to an API should be within the versioned package (e.g., yourapi.v1.SharedProtoMessage).

  • In scenarios where an API doesn’t consider itself to have a version, the API must use v1. (Omitted-version protos are prohibited.)

  • When a shared proto is identical, that proto should be duplicated to the other versioned package (e.g., copied and pasted into yourapi.v2.SharedProtoMessage).

What if a proto will never change?

There are some situations where it is useful to have an unversioned proto. These should generally apply to a complete product area or suite of APIs, not just a single API. In these situations, it may be possible to add it to our collections of common protos. Common protos are able to be used by many APIs, and are always unversioned.

Common protos shall always have a package structure ending in type (e.g. google.type, google.cloud.type).

Warning: This is a relatively rare occurrence. If you find yourself adding protos to your PA’s type directory frequently, double-check that this is actually where they belong.

For more information on common protos, consult AIP-213.