AIP-127 HTTP和gRPC转码
编号 | 127 |
---|---|
原文链接 | AIP-127: HTTP and gRPC Transcoding |
状态 | 批准 |
创建日期 | 2019-08-22 |
更新日期 | 2019-08-22 |
遵守面向资源设计的API使用RPC进行定义,但面向资源设计框架允许这些API表现为整体上符合REST/JSON约定的接口。这一点很重要,可以帮助开发者利用现有知识:超过80%的公开API遵守REST约定,开发者已经习惯了这种模式。
指南
API 必须 每个RPC提供HTTP定义,双向流式RPC除外。因为HTTP/1.1无法原生支持双向流式传输。提供双向流式方法的API 应该 提供一个不依赖双向流式传输的备选方法。
HTTP方法和路径
使用protobuf时,每个RPC 必须 使用 google.api.http
注解定义HTTP方法和路径:
rpc CreateBook(CreateBookRequest) returns (Book) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*}/books"
body: "book"
};
}
message CreateBookRequest {
// The publisher who will publish this book.
// When using HTTP/JSON, this field is automatically populated based
// on the URI, because of the `{parent=publishers/*}` syntax.
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
child_type: "library.googleapis.com/Book"
}];
// The book to create.
// When using HTTP/JSON, this field is populated based on the HTTP body,
// because of the `body: "book"` syntax.
Book book = 2 [(google.api.field_behavior) = REQUIRED];
// The user-specified ID for the book.
// When using HTTP/JSON, this field is populated based on a query string
// argument, such as `?bookId=foo`. This is the fallback for fields that
// are not included in either the URI or the body.
// Note that clients use camelCase format to communicate the field names
// to the service.
string book_id = 3;
}
- 第一个键(例子中的
post
)对应于HTTP方法。RPC 可以 使用get
、post
、patch
或delete
方法。- RPC 必须 对标准方法使用规范HTTP动词,如AIP-131、AIP-132、AIP-133、AIP-134和AIP-135中讨论的那样。
- RPC 应该 对自定义方法使用规范HTTP动词,如AIP-136中讨论的那样。
- RPC 不应该 使用
put
或custom
。
- 表示URI的值。
- URI 必须 使用
{foo=bar/*}
语法表示应在请求proto中填充的变量。当捕获资源名字时,变量 必须 包括完整的资源名字,而非仅仅是标识部分。 - URI 可以 使用嵌套域作为变量名。(还有,AIP-134要求
Update
请求必须这么做。) - URI 必须 使用
*
字符来表示标识部分,它匹配除/
之外的所有URI安全字符。如果需要匹配字符/
,URI 可以 使用**
作为URI的最后一段。
- URI 必须 使用
body
键定义了请求中将作为HTTP主体发送的单一顶层域。如果主体是 *,表示请求对象自身是HTTP主体。请求主体按照protobuf规范JSON编码生成JSON。- 使用
GET
或DELETE
HTTP动词的RPC 不得 定义body
。 - 创建(AIP-133)和更新(AIP-134)请求 必须 使用规定的
body
。 - 自定义方法(AIP-136) 应该 使用规定的
body
。 body
不得 包含嵌套域(或使用.
字符)。body
不得 与URI参数相同。body
不得 是repeated
域。- 域 不应 使用
json_name
注解改变JSON中的域名字,除非需要向后兼容。
- 使用
注意: 双向流式RPC不应该包含任何
google.api.http
注解。如果可以,服务 应该 提供等效的非流式RPC。
多URI绑定
有时一个RPC需要对应多个URI:
rpc CreateBook(CreateBookRequest) returns (Book) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*}/books"
body: "book"
additional_bindings: {
post: "/v1/{parent=authors/*}/books"
body: "book"
}
additional_bindings: {
post: "/v1/books"
body: "book"
}
};
}
- RPC 可以 定义任意数量的附加绑定。附加绑定结构与
google.api.http
注解相同(实际上这是一个递归引用)。 - RPC 不得 在附加绑定中嵌套定义附加绑定。
body
子句 必须 在顶级注解和每个附加绑定中相同。
修订记录
- 2022-08-18 :添加要求查询字符串参数名字使用camelCase格式的注释。
- 2021-01-06 :添加对
body
和嵌套域的明确描述。 - 2019-09-23 :添加关于请求主体编码的陈述,和避免使用
json_name
的指南。