AIP-122

Resource names

Most APIs expose resources (their primary nouns) which users are able to create, retrieve, and manipulate. Additionally, resources are named: each resource has a unique identifier that users use to reference that resource, and these names are what users should store as the canonical names for the resources.

Guidance

All resource names defined by an API must be unique within that API. (See the section on full resource names below for more information on referring to resources across APIs.)

Resource names are formatted according to the URI path schema, but without the leading slash:

publishers/123/books/les-miserables
users/vhugo1802
  • Resource name components should usually alternate between collection identifiers (example: publishers, books, users) and resource IDs (example: 123, les-miserables, vhugo1802).
  • Resource names must use the / character to separate individual segments of the resource name.
    • Non-terminal segments of a resource name must not contain a / character.
    • The terminal segment of a resource name should not contain a / character.
  • Resource names should only use ASCII characters that do not require URL-escaping when possible.
    • If Unicode characters must be used, resource names must be stored in Normalization Form C (see AIP-210).

Note: Resource names as described here are used within the scope of a single API (or else in situations where the owning API is clear from the context), and are only required to be unique within that scope. For this reason, they are sometimes called relative resource names to distinguish them from full resource names (discussed below).

Collection identifiers

The collection identifier segments in a resource name must be the plural form of the noun used for the resource. (For example, a collection of Publisher resources is called publishers in the resource name.)

  • Collection identifiers must be concise American English terms.
  • Collection identifiers must be in camelCase.
  • Collection identifiers must begin with a lower-cased letter and contain only ASCII letters and numbers (/[a-z][a-zA-Z0-9]*/).
  • Collection identifiers must be plural.
    • In situations where there is no plural word (“info”), or where the singular and plural terms are the same (“moose”), the non-pluralized (singular) form is correct. Collection segments must not “coin” words by adding “s” in such cases (e.g, avoid “infos”).

Nested collections

If a resource name contains multiple levels of a hierarchy, and a parent collection’s name is used as a prefix for the child resource’s name, the child collection’s name may omit the prefix. For example, given a collection of UserEvent resources that would normally be nested underneath users:

users/vhugo1802/userEvents/birthday-dinner-226

An API should use the less-redundant form:

users/vhugo1802/events/birthday-dinner-226

In this situation, the message is still called UserEvent; only the resource name is shortened.

Note: APIs wishing to do this must follow this format consistently throughout the API, or else not at all.

Resource ID segments

A resource ID segment identifies the resource within its parent collection. In the resource name publishers/123/books/les-miserables, 123 is the resource ID for the publisher, and les-miserables is the resource ID for the book.

  • Resource IDs may be either always set by users (required on resource creation), optionally set by users (optional on resource creation, server-generated if unset), or never set by users (not accepted at resource creation). They should be immutable once created.
    • If resource IDs are user-settable, the API must document allowed formats.
    • If resource IDs are not user-settable, the API should document the basic format, and any upper boundaries (for example, “at most 256 characters”).
    • For more information, see the create standard method.
  • Resource IDs should only use characters that do not require URL-escaping.
    • Characters outside of ASCII are discouraged; however, if Unicode characters are necessary, APIs must follow guidance in AIP-210.

Resource ID aliases

It is sometimes valuable to provide an alias for common lookup patterns for resource IDs. For example, an API with users at the top of its resource hierarchy may wish to provide users/me as a shortcut for retrieving information for the authenticated user.

APIs may provide programmatic aliases for common lookup patterns. However, all data returned from the API must use the canonical resource name.

Full resource names

In most cases, resource names are used within a single API only, or else they are used in contexts where the owning API is clear (for example, string pubsub_topic).

However, sometimes it is necessary for APIs to refer to resources in an arbitrary API. In this situation, they should use the full resource name. The full resource name is a schemeless URI with the owning API’s service endpoint, followed by the relative resource name:

//library.googleapis.com/publishers/123/books/les-miserables
//calendar.googleapis.com/users/vhugo1802

Resource URIs

The full resource name is a schemeless URI, but slightly distinct from the full URIs we use to access a resource. The latter adds two components: the protocol (HTTPS) and the API version:

https://library.googleapis.com/v1/publishers/123/books/les-miserables
https://calendar.googleapis.com/v3/users/vhugo1802

The version is not included in the full resource name because the full resource name is expected to persist from version to version. Even though the API surface may change between major versions, multiple major versions of the same API are expected to use the same underlying data.

Note: The correlation between the full resource name and the service’s hostname is by convention. In particular, one service is able to have multiple hostnames (example use cases include regionalization or staging environments), and the full resource does not change between these.

Fields representing resource names

When defining a resource, the first field should be the resource name, which must be of type string and must be called name for the resource name.

// A representation of a book in the library.
message Book {
  // The resource name of the book.
  // Format: publishers/{publisher}/books/{book}
  string name = 1;

  // Other fields...
}

When defining a method that retrieves or acts on an already-existing resource (such as GetBook or ArchiveBook), the first field of the request message should be the resource name, which must be of type string and must be called name for the resource name.

// Request message for ArchiveBook
message ArchiveBookRequest {
  // The book to archive.
  // Format: publishers/{publisher}/books/{book}
  string name = 1;

  // Other fields...
}

Note: Fields must not be called name except for this purpose. For other use cases, either use a different term or prepend an adjective (for example: display_name).

Fields representing a resource’s parent

When defining a method that retrieves resources from a collection or adds a new resource to a collection (such as ListBooks or CreateBook), the first field of the request message should be of type string and should be called parent for the resource name of the collection.

// Request message for ListBooks.
message ListBooksRequest {
  // The publisher to list books from.
  // Format: publishers/{publisher_id}
  string parent = 1;

  // Other fields (e.g. page_size, page_token, filter, etc.)...
}

Note: Fields should not be called parent except for this purpose. For other use cases, use a synonymous term if possible.

Fields representing another resource

When referencing a resource name for a different resource, the field should be of type string for the resource name, and the field name should be equivalent to the corresponding message’s name in snake case.

  • Field names may include a leading adjective if appropriate (such as string dusty_book).
  • Field names should not use the _name suffix unless the field would be ambiguous without it (e.g., crypto_key_name)
// A representation of a book in a library.
message Book {
  // Name of the book.
  // Format is `publishers/{publisher}/books/{book}`
  string name = 1;

  // The shelf where the book currently sits.
  // Format is `shelves/{shelf}`.
  string shelf = 2;

  // Other fields...
}

Note: When referring to other resources in this way, we use the resource name as the value, not just the ID component. APIs should use the resource name to reference resources when possible. If using the ID component alone is strictly necessary, use an _id suffix (e.g. shelf_id).

Further reading

  • For evolving resource names over time, see AIP-180.

Changelog

  • 2019-08-01: Changed the examples from “shelves” to “publishers”, to present a better example of resource ownership. Also changed the final example from a Pub/Sub example to the usual Book example.
  • 2019-07-30: Changed the nested collection brevity suggestion from “may” to “should”