Featured image of post gRPC-google.api的HttpRule介绍

gRPC-google.api的HttpRule介绍

gRPC中google.api对http请求中的一些映射规则及HttpRule的简介

HTTP Rule

gRPC Transcoding 是一种用于在 gRPC 方法和一个或多个 HTTP REST 端点之间进行映射的功能。它允许开发人员构建一个同时支持 gRPC API 和 REST API 的 API 服务。HttpRule 定义 gRPC/REST 映射的模式。映射指定 gRPC 请求消息的不同部分如何映射到 URL 路径、URL 查询参数和 HTTP 请求正文。它还控制 gRPC 响应消息如何映射到 HTTP 响应正文。HttpRule 通常被指定为 google.api.http gRPC 方法的注解。

每个映射指定一个 URL 路径模板和一个 HTTP 方法。路径模板可以引用 gRPC 请求消息中的一个或多个字段,只要每个字段是原始(非消息)类型的非重复字段即可。路径模板控制请求消息的字段如何映射到 URL 路径。

例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
service Messaging {
  rpc GetMessage(GetMessageRequest) returns (Message) {
    option (google.api.http) = {
        get: "/v1/{name=messages/*}"
    };
  }
}
message GetMessageRequest {
  string name = 1; // Mapped to URL path.
}
message Message {
  string text = 1; // The resource content.
}

这启用了 HTTP REST 到 gRPC 的映射,如下:

HTTP gRPC
GET /v1/messages/123456 GetMessage(name: “messages/123456”)

如果没有 HTTP 请求 body,则请求消息中没有被路径模板绑定的任何字段都会自动成为 HTTP query parameters。例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
service Messaging {
  rpc GetMessage(GetMessageRequest) returns (Message) {
    option (google.api.http) = {
        get:"/v1/messages/{message_id}"
    };
  }
}
message GetMessageRequest {
  message SubMessage {
    string subfield = 1;
  }
  string message_id = 1; // Mapped to URL path.
  int64 revision = 2;    // Mapped to URL query parameter `revision`.
  SubMessage sub = 3;    // Mapped to URL query parameter `sub.subfield`.
}

这启用了 HTTP JSON 到 RPC 映射,如下:

HTTP gRPC
GET /v1/messages/123456?revision=2&sub.subfield=foo GetMessage(message_id: “123456” revision: 2 sub: SubMessage(subfield: “foo”))

这里需要注意的是,映射到 URL 查询参数的字段必须具有原始类型或重复的原始类型或非重复的消息类型。在 repeated 类型的情况下,参数可以在 URL 中重复为...?param=A&param=B. 在 message 类型的情况下,消息的每个字段都映射到一个单独的参数,例如...?foo.a=A&foo.b=B&foo.c=C

对于可以添加 body 的 HTTP 方法,body 字段指定映射。比如 message 集合上的 REST update 方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
service Messaging {
  rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
    option (google.api.http) = {
      patch: "/v1/messages/{message_id}"
      body: "message"
    };
  }
}
message UpdateMessageRequest {
  string message_id = 1; // mapped to the URL
  Message message = 2;   // mapped to the body
}

启用了以下 HTTP JSON 到 RPC 映射,其中请求正文中 JSON 的表示由 protos JSON 编码确定:

HTTP gRPC
PATCH /v1/messages/123456 { “text”: “Hi!” } UpdateMessage(message_id: “123456” message { text: “Hi!” })

可以在 body 映射中使用*来表示所有不受路径模板绑定的字段都应该映射到 body中。比如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
service Messaging {
  rpc UpdateMessage(Message) returns (Message) {
    option (google.api.http) = {
      patch: "/v1/messages/{message_id}"
      body: "*"
    };
  }
}
message Message {
  string message_id = 1;
  string text = 2;
}

启用了 HTTP JSON 到 RPC 映射,如下:

HTTP gRPC
PATCH /v1/messages/123456 { “text”: “Hi!” } UpdateMessage(message_id: “123456” text: “Hi!")

请注意,在正文映射中使用*时,不可能有 HTTP 参数,因为所有不受路径绑定的字段都以正文结尾。 这使得该选项在定义 REST API 时很少在实践中使用。*的常见用法是在根本不使用 URL 来传输数据的自定义方法中。

可以使用该additional_bindings选项为一个 RPC 定义多个 HTTP 方法。例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
service Messaging {
  rpc GetMessage(GetMessageRequest) returns (Message) {
    option (google.api.http) = {
      get: "/v1/messages/{message_id}"
      additional_bindings {
        get: "/v1/users/{user_id}/messages/{message_id}"
      }
    };
  }
}
message GetMessageRequest {
  string message_id = 1;
  string user_id = 2;
}

启用了两种可选的 HTTP JSON 到 RPC 映射,如下:

HTTP gRPC
GET /v1/messages/123456 GetMessage(message_id: “123456”)
GET /v1/users/me/messages/123456 GetMessage(user_id: “me” message_id: “123456”)

接下来介绍 HTTP 的映射规则:

  1. 请求字段(请求消息中的递归扩展嵌套消息)分为以下三类:
  • 路径模板引用的字段。它们通过 URL 路径传递。
  • 引用的字段HttpRule.body。它们通过 HTTP 请求正文传递。
  • 所有其他字段都是通过 URL 查询参数传递的,参数名称是请求消息中的字段路径。一个重复的字段可以表示为同名的多个查询参数。
  1. 如果HttpRule.body为*,则没有 URL 查询参数,所有字段都通过 URL 路径和 HTTP 请求正文传递。
  2. 如果HttpRule.body省略,则没有 HTTP 请求正文,所有字段都通过 URL 路径和 URL 查询参数传递。
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy