在面向资源的 API 中,资源是命名实体,资源名称是其标识符。每一个资源 必须( MUST ) 有惟一的资源名称。资源名称由资源本身的 ID,任一父资源的 ID 及其 API 服务名称组成。下面咱们将看一看资源 ID 和资源名是如何构成的。node
gRPC API 应该为资源名使用无协议(scheme-less)的 URI。它们一般遵循 REST URL 惯例而且其行为与网络文件路径很是类似。它们能很是容易地映射到 REST API:详细内容查看标准方法。api
集合是一种特殊类型的资源,它包含了相同类型子资源的列表。例如,目录是文件资源的集合。集合的资源 ID 叫作集合 ID。网络
资源名称由集合 ID 和资源 ID 按层次组织造成,并以斜杠(/)分隔。若是资源包含子资源,子资源名称的格式是父资源名称后面加上子资源 ID,一样地使用斜杠分隔。app
例 1:一个存储服务具备 buckets
集合,每一个 bucket 具备 objects
集合:less
| API 服务名 | 集合 ID | 资源 ID | 集合 ID | 资源 ID |
| - | - | - | - | - |
| //storage.googleapis.com | /buckets | /bucket-id | /objects| /object-id |ide
例 2:一个具备 users
集合的邮件服务,每一个用户具备 settings
子资源, settings
子资源具备 customFrom
和另外的子资源:post
| API 服务名 | 集合 ID | 资源 ID | 资源 ID | 资源 ID |
| - | - | - | - | - |
| //mail.googleapis.com | /users | /name@example.com | /settings| /customFrom |ui
API 设计者能够为资源和集合 ID 选择任何可接受的值,只要它们在资源层次结构中是惟一的便可。你能够在下面找到有关选择适当资源和集合 ID 的更多指南。google
无协议(scheme-less) URI 由兼容 DNS 的 API 服务名和资源路径组成。资源路径也称为相对资源名。例如:
"//library.googleapis.com/shelves/shelf1/books/book2"
API 服务名用于客户端定位 API 服务端点,若是只为内部服务,它能够(may)是假的 DNS 名。若是 API 服务名在上下文中显而易见的话则会常用相对资源名。
没有斜杠(/)开头的 URI 路径标识了 API 服务中的资源。例如:
"shelves/shelf1/books/book2"
使用非空的 URI 段标识其父资源中的资源。请看上面的例子。
资源名称后面跟随的资源 ID 能够(may) 具备不仅一个 URI 段,例如:
| 集合 ID | 资源 ID |
| - | - |
| files | /source/py/parser.py |
若是能够的话,API 服务应该(should)使用 URL 友好的资源 ID。资源 ID 必须(must) 明确地记录在文档中,无论它们是由客户端仍是服务端分配的。例如,文件名通常由客户端分配,而邮件信息 ID 通常由服务端分配。
使用非空的 URI 段标识其父资源中的资源集合。请看上面的例子。
由于集合 ID 常常出如今生成的客户端库中,它们 必须(must) 符合如下要求:
必须(must) 是合法的 C/C++ 标识符
必须(must) 是复数形式的首字母小写的驼峰命名
必须(must) 使用清晰简明的英语词汇
应该(should) 避免或限定过于笼统的术语。例如:RowValue
优于 Value
。除非明肯定义,不然 应该(should) 避免使用以下术语:
Element
Entry
Instance
Item
Object
Resource
Type
Value
完整的资源名相似普通的 URL,但它们并不相同。一样的资源可以经过不一样版本或不一样协议的 API 来暴露出去。完整的资源名并无指定这些信息,因此必须将它映射到特定的协议和 API 版本上才能直接地使用。
为了经过 REST API 使用完整的资源名,必须(must) 使用以下方法将其映射为 REST URL:在服务名前添加 HTTPS 协议、在资源路径前添加 API 主版本号、将资源路径进行 URL 转义。例如:
// 这是日历事件的资源名 "//calendar.googleapis.com/users/john smith/events/123" // 这是对应的 HTTP URL "https://calendar.googleapis.com/v3/users/john%20smith/events/123"
除非有向后兼容的问题,Google API 必须(must) 使用字符串来表示资源名。资源名 应该(should) 像普通文件路径那样处理,而且不支持百分号编码。
对于资源定义,第一个字段 应该(should) 是资源名称的字符串字段,它 应该(should) 叫做 name
。
注意:像 display_name
、first_name
、last_name
、full_name
这种与名字相关的字段 应该(should) 给出定义来避免混乱。
例子:
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 { // book 的资源名。必须是"shelves/*/books/*"的格式 // 例如:"shelves/shelf1/books/book2". string name = 1; // ... 其余属性 } message GetBookRequest { // 一个 book 的资源名。例如:"shelves/shelf1/books/book2" string name = 1; } message CreateBookRequest { // 建立 book 的父资源名 // 例如:"shelves/shelf1" string parent = 1; // 被建立的 book 资源。客户端必定不能(must not)设置 `Book.name` 字段 Book book = 2; }
提示:为了资源名称的一致性,开始的斜杠 必定不能(must not) 被 URL 模版变量捕获。例如,必须(must) 使用 URL 模版 "/v1/{name=shelves/*/books/*}"
而不是 "/v1{name=/shelves/*/books/*}"
。