In resource-oriented APIs, resources are named entities, and resource namesare their identifiers. Each resource must have its own unique resource name.The resource name is made up of the ID of the resource itself, the IDs of anyparent resources, and its API service name. We'll look at resource IDs and howa resource name is constructed below.
gRPC APIs should use scheme-lessURIs forresource names. They generally follow the REST URL conventions and behave muchlike network file paths. They can be easily mapped to REST URLs: see theStandard Methods section for details.
A collection is a special kind of resource that contains a list ofsub-resources of identical type. For example, a directory is a collection offile resources. The resource ID for a collection is called collection ID.
The resource name is organized hierarchically using collection IDs andresource IDs, separated by forward slashes. If a resource contains asub-resource, the sub-resource's name is formed by specifying the parentresource name followed by the sub-resource's ID - again, separated byforward slashes.
Example 1: A storage service has a collection of buckets
, where each buckethas a collection of objects
:
API Service Name | Collection ID | Resource ID | Collection ID | Resource ID |
---|---|---|---|---|
//storage.googleapis.com | /buckets | /bucket-id | /objects | /object-id |
Example 2: An email service has a collection of users
. Each user has asettings
sub-resource, and the settings
sub-resource has a number ofother sub-resources, including customFrom
:
API Service Name | Collection ID | Resource ID | Resource ID | Resource ID |
---|---|---|---|---|
//mail.googleapis.com | /users | /[email protected] | /settings | /customFrom |
An API producer can choose any acceptable value for resource and collectionIDs as long as they are unique within the resource hierarchy. You can findmore guidelines for choosing appropriate resource and collection IDs below.
By splitting the resource name, such as name.split("/")[n]
, one can obtainthe individual collection IDs and resource IDs, assuming none of the segmentscontains any forward slash.
Full Resource Name
A scheme-less URI consisting of aDNS-compatible API service name and aresource path. The resource path is also known as relative resource name.For example:
"//library.googleapis.com/shelves/shelf1/books/book2"
The API service name is for clients to locate the API service endpoint; itmay be a fake DNS name for internal-only services. If the API servicename is obvious from the context, relative resource names are often used.
Relative Resource Name
A URI path (path-noscheme)without the leading "/". It identifies a resource within the API service.For example:
"shelves/shelf1/books/book2"
Resource ID
A resource ID typically consists of one or more non-empty URI segments(segment-nz-nc) thatidentify the resource within its parent resource, see above examples.The non-trailing resource ID in a resource name must have exactly oneURL segment, while the trailing resource ID in a resource name mayhave more than one URI segment. For example:
Collection ID | Resource ID |
---|---|
files | source/py/parser.py |
API services should use URL-friendly resource IDs when feasible.Resource IDs must be clearly documented whether they are assigned by theclient, the server, or either. For example, file names are typicallyassigned by clients, while email message IDs are typically assigned byservers.
Collection ID
A non-empty URI segment(segment-nz-nc)identifying the collection resource within its parent resource,see above examples.
Because collection IDs often appear in the generated client libraries, theymust conform to the following requirements:
- Must be valid C/C++ identifiers.
- Must be in plural form with lowerCamel case. If the term doesn't havesuitable plural form, such as "evidence" and "weather", the singular formshould be used.
- Must use clear and concise English terms.
- Overly general terms should be avoided or qualified. For example,
rowValues
is preferred tovalues
. The following terms should beavoided without qualification:- elements
- entries
- instances
- items
- objects
- resources
- types
- values
Resource Name vs URL
While full resource names resemble normal URLs, they are not the samething. A single resource can be exposed by different API versions, APIprotocols, or API network endpoints. The full resource name does not specifysuch information, so it must be mapped to a specific API version and APIprotocol for actual use.
To use a full resource name via REST APIs, it must beconverted to a REST URL by adding the HTTPS scheme before the servicename, adding the API major version before the resource path, andURL-escaping the resource path. For example:
// This is a calendar event resource name."//calendar.googleapis.com/users/john smith/events/123"// This is the corresponding HTTP URL."https://calendar.googleapis.com/v3/users/john%20smith/events/123"
Resource Name as String
Google APIs must represent resource names using plain strings, unlessbackward compatibility is an issue. Resource names should be handledlike normal file paths. When a resource name is passed between differentcomponents, it must be treated as an atomic value and must not haveany data loss.
For resource definitions, the first field should be a string field forthe resource name, and it should be called name
.
For example:
service LibraryService { rpc GetBook(GetBookRequest) returns (Book) { option (google.api.http) = { get: "/v1/{name=shelves/*/books/*}" }; }; rpc CreateBook(CreateBookRequest) returns (Book) { option (google.api.http) = { post: "/v1/{parent=shelves/*}/books" body: "book" }; };}message Book { // Resource name of the book. It must have the format of "shelves/*/books/*". // For example: "shelves/shelf1/books/book2". string name = 1; // ... other properties}message GetBookRequest { // Resource name of a book. For example: "shelves/shelf1/books/book2". string name = 1;}message CreateBookRequest { // Resource name of the parent resource where to create the book. // For example: "shelves/shelf1". string parent = 1; // The Book resource to be created. Client must not set the `Book.name` field. Book book = 2;}
Note: For consistency of resource names, the leading forward slashmust not be captured by any URL template variable. For example, URLtemplate "/v1/{name=shelves/*/books/*}"
must be used instead of"/v1{name=/shelves/*/books/*}"
.
Questions
Q: Why not use resource IDs to identify a resource?
For any large system, there are many kinds of resources. To use resource IDsto identify a resource, we actually use a resource-specific tuple to identifya resource, such as (bucket, object)
or (user, album, photo)
. Itcreates several major problems:
- Developers have to understand and remember such anonymous tuples.
- Passing tuples is generally harder than passing strings.
- Centralized infrastructures, such as logging and access control systems,don't understand specialized tuples.
- Specialized tuples limit API design flexibility, such as providingreusable API interfaces. For example,Long Running Operationscan work with many other API interfaces because they use flexible resourcenames.
Q: Why is the resource name field called name
instead of id
?
The resource name field is named after the concept of resource "name". Ingeneral, we find the concept of name
is confusing to developers. For example,is filename really just the name or the full path? By reserving the standardfield name
, developers are forced to choose a more proper term,such as display_name
or title
or full_name
.
Q: How should I generate and parse resource names?
Resource names behave like file paths. You can use printf()
to generateresource names from resource ids. You can use split()
to parse resourcenames into resource ids. Note that some trailing Resource IDcan have multiple URI segments separated by /
, like file path.