在面向資源的 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/*}"
。