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. 大多数 API 都公开了用户能够创建、检索和操作的资源(它们的主要名词)。 每个资源都有一个用户用来引用该资源的唯一标识符,这些名称是用户应该存储的资源的规范名称。

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.) API定义的所有资源名称必须在该API中是唯一的。

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.
  • 资源名称通常应该由集合ID(比如: publishers, books, users)和资源ID(例如: 123, les-miserables, vhugo1802).

  • 资源名称必须使用 / 字符来分隔各个段的资源名称。

    • 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 characters available in DNS names, as defined by RFC-1123.

    • Additionally, resource IDs should not use upper-case letters.  此外,资源 ID 不应使用大写字母。
    • If additional characters are necessary, resource names should not use characters that require URL-escaping, or characters outside of ASCII. 如果需要额外的字符,资源名称不应该使用需要URL转义的字符或ASCII 以外的字符。

    • If Unicode characters can not be avoided, resource names must be stored in Normalization Form C (see AIP-210). 如果不能避免Unicode字符,资源名必须存储 标准化形式 C (see AIP-210).

    • Resources must expose a name field that contains its resource name. 资源必须公开一个包含其资源名称的名称字段。
    • Resources may provide the resource ID as a separate field (e.g. book_id). 资源可以提供资源 ID 作为单独的字段(例如,book_id)。
    • Resources may expose a separate, system-generated unique ID field (uid). 资源也许会暴露一个独立的系统生产的唯一ID字段(uid)。
    • Resources must not expose tuples, self-links, or other forms of resource identification. 资源不得暴露元组、自链接或其他形式的资源标识。
    • All ID fields should be strings.  所有 ID 字段 为字符串。 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). 此处所述的资源名称在单个 API 的范围内使用(或者在拥有 API 的上下文中很清楚的情况下使用),并且只需要在该范围内是唯一的。因此,它们有时称为相对资源名称,以将其与完整资源名称区分开来(下面讨论)。

Collection identifiers 集合ID

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.) 资源名称中的集合标识符段 必须 是用于资源的名词的复数形式。(例如,Publisher资源的集合在资源名称中称为publishers

  • Collection identifiers must be concise American English terms. 集合标识符 必须 是简明的美式英语术语。
  • Collection identifiers must be in camelCase. 集合标识符 必须camelCase
  • Collection identifiers must begin with a lower-cased letter and contain only ASCII letters and numbers (/[a-z][a-zA-Z0-9]*/). 集合标识符 必须 以小写字母开头,并且仅包含ASCII字母和数字(/[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").
  • 集合标识符 必须 为复数形式。
    • 在没有复数词("info")的情况下,或者单数 和复数术语是相同的("moose"),非复数(单数)形式 是正确的。集合段 不得 通过在 中添加"s"来表示"coin"字样 此类情况(例如,避免使用"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 下的 UserEvent 资源:

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. 在这种情况下,message 仍然被称为 UserEvent; 只有资源名称被缩短。

Note: APIs wishing to do this must follow this format consistently throughout the API, or else not at all. 希望执行此操作的 API 必须始终遵循此格式在整个 API 中,或者根本没有。

Resource ID segments 资源 ID 段

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. 资源 ID 段标识其父集合中的资源。 在资源名称publishers/123/books/les-miserables中,123是出版商的资源ID,les-miserables是图书的资源ID。

  • 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. 资源 ID 可以始终由用户设置(创建资源时需要),可选地由用户设置(在创建资源时可选,如果未设置,则由服务器生成),或者从不由用户设置(在创建资源时不接受)。 它们应该在创建后是不可变的。
    • If resource IDs are user-settable, the API must document allowed formats. User-settable resource IDs should conform to RFC-1034; which restricts to letters, numbers, and hyphen, with the first character a letter, the last a letter or a number, and a 63 character maximum. 如果资源 ID 可由用户设置,则 API 必须记录允许的格式。 用户可设置的资源 ID 应该符合 RFC-1034;限制为字母、数字和连字符,第一个字符为字母,最后一个字符为字母或数字,最多 63 个字符。

      • Additionally, user-settable resource IDs should restrict letters to lower-case (^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$). 此外,用户可设置的资源 ID 将字母限制为小写。
      • Characters outside of ASCII should not be permitted; however, if Unicode characters are necessary, APIs must follow guidance in AIP-210.ASCII 以外的字符不应该被允许; 但是,如果需要 Unicode 字符,API 必须遵循AIP-210

      • User-settable IDs should not be permitted to be a UUID (or any value that syntactically appears to be a UUID). 用户可设置的 ID 不应被允许为 UUID(或任何在语法上看起来是 UUID 的值)。

        • If resource IDs are not user-settable, the API should document the basic format, and any upper boundaries (for example, "at most 63 characters"). 如果资源 ID 不是用户可设置的,API 应该记录基本格式和任何上限(例如,“最多 63 个字符”)。
        • For more information, see the create standard method.

Important: Resources that are declarative-friendly (AIP-128) must use user-settable resource IDs. 声明友好的资源(AIP-128必须使用用户可设置的资源 ID。

Resource ID aliases 资源 ID 别名

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. 有时为资源 ID 的常见查找模式提供别名很有价值。 例如,在其资源层次结构顶部具有users的 API 可能希望提供 users/me作为检索经过身份验证的用户信息的快捷方式。

APIs may provide programmatic aliases for common lookup patterns. However, all data returned from the API must use the canonical resource name. API 可以为常见的查找模式提供编程别名。 然而,从 API 返回的所有数据必须使用规范的资源名称

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). 在大多数情况下,资源名称仅在单个 API 中使用,或者在拥有 API 明确的上下文中使用(for example, string pubsub_topic).

However, sometimes it is necessary for services to refer to resources in an arbitrary API. In this situation, the service should use the full resource name, a schemeless URI with the owning API's service endpoint, followed by the relative resource name: 但是,有时服务需要引用任意 API 中的资源。 在这种情况下,服务应该使用完整的资源名称,即拥有 API 服务端点的schemeless的URI,后跟相对资源名称:

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

Note: The full resource name should not be used for cross-API references where the owning API is clear; it is only used if a field refers to resources in multiple APIs where ambiguity is possible. 完整的资源名称不应用于明确拥有 API 的跨 API 引用; 它仅在字段引用多个 API 中可能存在歧义的资源时使用。

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: 完整的资源名称是schemeless的 URI,但与完整的资源名称略有不同 我们用来访问资源的 URI。 后者增加了两个组件:协议 (HTTPS) 和 API 版本:

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. 版本不包含在完整资源名称中,因为完整资源名称预计会在版本之间保持不变。 尽管 API 表面可能在主要版本之间发生变化,但同一 API 的多个主要版本应该使用相同的底层数据。

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. The message should include a google.api.resource annotation declaring the type (see AIP-123 for more on this). 定义资源时,第一个字段应该是资源名称,必须string类型并且必须称为name作为资源名称。 message应该包含声明类型的 google.api.resource 注释(有关此内容的更多信息,请参见 AIP-123)。

// A representation of a book in the library.
message Book {
  option (google.api.resource) = {
    type: "library.googleapis.com/Book"
    pattern: "publishers/{publisher}/books/{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. The field should also be annotated with the google.api.resource_reference annotation, referencing the resource type (AIP-123). 定义检索或作用于现有资源的方法时 (如GetBookArchiveBook),请求消息的第一个字段 应该是资源名称,必须string类型并且 必须 为资源名称命名为 name。 字段应该也是 使用 google.api.resource_reference 注释进行注释,引用 资源类型(AIP-123)。

// Request message for ArchiveBook
message ArchiveBookRequest {
  // The book to archive.
  // Format: publishers/{publisher}/books/{book}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "library.googleapis.com/Book"
    }];

  // 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). 除此目的外,字段不得称为name。对于其他用例,要么使用不同的术语,要么在前面加上形容词(例如: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. The parent field should also be annotated with the google.api.resource_reference annotation, referencing the parent's resource type (AIP-123). 当定义从集合中检索资源或将新资源添加到集合中的方法时(例如ListBooksCreateBook),请求消息的第一个字段应该string类型和 应该被调用 parent 为集合的资源名称。 parent 字段也应该使用 google.api.resource_reference 注释进行注释,引用父资源类型 (AIP-123)。

// Request message for ListBooks.
message ListBooksRequest {
  // The publisher to list books from.
  // Format: publishers/{publisher_id}
  string parent = 1 [(google.api.resource_reference) = {
    type: "library.googleapis.com/Publisher"
  }];

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

If there is more than one possible parent type, the parent field should be annotated with the child_type key on google.api.resource_reference instead: 如果有多个可能的父类型,则 parent 字段应该 使用 google.api.resource_reference 上的 child_type 键进行注释:

// Request message for ListBooks.
message ListBooksRequest {
  // The parent to list books from.
  // Format:
  //   - publishers/{publisher_id}
  //   - authors/{author_id}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "library.googleapis.com/Book"
    }];

  // 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). 字段名称可以在适当的情况下包含一个前导形容词(例如 stringdusty_book)。
  • Field names should not use the _name suffix unless the field would be ambiguous without it (e.g., crypto_key_name) 字段名称不应使用 _name 后缀,除非该字段没有它会模棱两可(例如,crypto key_name
  • Fields representing another resource should provide the google.api.resource_reference annotation with the resource type being referenced. 代表另一个资源的字段应该提供google.api.resource_reference 注释与被引用的资源类型。
// A representation of a book in a library.
message Book {
  option (google.api.resource) = {
    type: "library.googleapis.com/Book"
    pattern: "publishers/{publisher}/books/{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 [(google.api.resource_reference) = {
    type: "library.googleapis.com/Shelf"
  }];

  // Other fields...
}

Note: When referring to other resources in this way, we use the resource name as the value, not just the ID component. Services should use the resource name to reference resources when possible. If using the ID component alone is strictly necessary, the field should use an _id suffix (e.g. shelf_id). 以这种方式引用其他资源时,我们使用资源名称作为值,而不仅仅是 ID 组件。 服务应该尽可能使用资源名称来引用资源。 如果必须单独使用 ID 组件,则字段应该使用 _id 后缀(例如 shelf_id)。

Further reading

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

Changelog

  • 2020-10-06: Added declarative-friendly guidance, and tightened character set restrictions.
  • 2020-10-05: Clarified when full resource names are used.
  • 2020-05-19: Clarified that resource IDs avoid capital characters, not the entire resource name.
  • 2020-04-27: Tighten the restriction on valid characters.
  • 2019-12-05: Added guidance for resource annotations.
  • 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"