AIP-123
Resource types
Most APIs expose resources (their primary nouns) which users are able to
create, retrieve, and manipulate. APIs are allowed to name their resource types
as they see fit, and are only required to ensure uniqueness within that API.
This means that it is possible (and often desirable) for different APIs to use
the same type name. For example, a Memcache and Redis API would both want to
use Instance
as a type name.
When mapping the relationships between APIs and their resources, however, it becomes important to have a single, globally-unique type name. Additionally, tools such as Kubernetes or GraphQL interact with APIs from multiple providers.
Terminology
In the guidance below, we use the following terms:
- Service Name: This is the name defined in the service configuration.
This usually (but not necessarily) matches the hostname that users use to
call the service. Example:
pubsub.googleapis.com
. This is equivalent to an API Group in Kubernetes. - Type: This is the name used for the type within the API. This should match the name of the protobuf message. This is equivalent to an Object in Kubernetes.
Guidance
APIs must define a resource type for each resource in the API, according to
the following pattern: {Service Name}/{Type}
. The type name must:
- Start with an uppercase letter.
- Only contain alphanumeric characters.
- Be of the singular form of the noun.
- Use PascalCase (UpperCamelCase).
Examples
Examples of resource types include:
pubsub.googleapis.com/Topic
pubsub.googleapis.com/Subscription
spanner.googleapis.com/Database
spanner.googleapis.com/Instance
networking.istio.io/Instance
Annotating resource types
APIs should annotate the resource types for each resource in the API using
the google.api.resource
annotation:
// A representation of a Pub/Sub topic.
message Topic {
option (google.api.resource) = {
type: "pubsub.googleapis.com/Topic"
pattern: "projects/{project}/topics/{topic}"
singular: "topic"
plural: "topics"
};
// The resource name of the topic.
string name = 1;
// Other fields...
}
- Patterns must correspond to the resource name.
- Pattern variables (the segments within braces) must use
snake_case
, and must not use an_id
suffix. - Pattern variables must conform to the format
[a-z][_a-z0-9]*[a-z0-9]
. - Singular must be the lower camel case of the type.
- Pattern variables must be the singular form of the resource type e.g.
a pattern variable representing a
Topic
resource ID is named{topic}
.
- Pattern variables must be the singular form of the resource type e.g.
a pattern variable representing a
- Plural must be the lower camel case plural of the singular.
- Pattern collection identifier segments must match the plural of the resources, except in the case of nested collections.
Pattern uniqueness
When multiple patterns are defined within a resource, these patterns must
be mutually unique, where uniqueness is defined as being by-character identical
once all resource ID path segments have been removed, leaving all /
separators.
Therefore the following two patterns must not be defined within the same resource:
user/{user}
user/{user_part_1}~{user_part_2}
Rationale
Singular and Plural
Well-defined singular and plurals of a resource enable clients to determine the proper name to use in code and documentation.
lowerCamelCase can be translated into other common forms of a resource name such as UpperCamelCase and snake_case.
Changelog
- 2023-05-06: Adding requirement of singular and plural.
- 2023-01-28: Clarifying guidance for the resource type name.
- 2022-10-28: Added pattern variable format guidance.
- 2020-05-14: Added pattern uniqueness.
- 2019-12-05: Added guidance on patterns.
- 2019-07-17: Fleshed out the annotation example somewhat.