前言
这个是在定义gRPC服务时遇到的知识点。HttpRule定义了gRPC方法与HTTP方法的映射关系,具体来说,是请求和相应之间的对应关系。这篇博文仅作简单对应关系的介绍,重在使用,不深究原理。
另:本人还是新手,如有描述上的不当请不吝赐教。
一、gRPC
gRPC是Google在rpc基础上开发的新功能。RPC,远程过程调用,简单来说就是可以远程访问其他服务器上的服务。最直白的例子就是:我有两个主机A和B。A中启动了一个服务;B可以通过RPC的方式调用A中的服务。当然,RPC可以不是两台主机间的描述,同一台主机上两个进程也属于远程过程调用。
gRPC的使用方法:
- 定义proto文件;
- 下载grpc,生成代码;
- 编写服务端代码:主要是对于定义的服务的实现;
- 编写grpc服务器代码:包括在哪个端口监听,等功能;
- 编写客户端代码:访问服务端方法。
gRPC的优点:
- 是跨语言的;服务端和客户端可以使用不同的程序语言,也可进行通信;
- 也可以通过HTTP请求,访问服务。
这里就涉及到http方法和grpc方法之间的映射关系。
二、HttpRule
在定义proto文件时,考虑到grpc需要通过http方法进行访问,因此在grpc方法中需要定义与http方法的映射关系。HttpRule即规定了两者映射规则。先简单总结如下:
- 通过
google.api.http标志与http方法间的映射; - 通过
additional_bindings与多个http方法实现映射; - 通过
url模板定义映射关系; - url模板可以指定grpc请求消息中的多个参数;
- 在没有定义请求体时,grpc请求消息中没有被绑定到url模板中的参数会自动成为http查询参数;
- 请求体值为*时,没有映射到url模板的所有参数都在请求体中;此时不允许http查询参数;
这里提到的http查询参数,即在url中通过?name=jason&sex=male定义的查询参数。
url模板中定义的参数,即在映射规则中写的url路径。
1. 简单Url模板
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.
}
这里的/v1/{name=messages/*}为url模板。它定义了在http请求方法中,v1后的内容与请求消息GetMessageRequest的name属性之间的映射关系:
| HTTP | gRPC |
|---|---|
| GET /v1/messages/123456 | GetMessage(name: “messages/123456”) |
2. 没有绑定在url模板中的请求消息
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`.
}
这里的url请求模板:/v1/messages/{message_id},定义了http方法中参数与请求消息GetMEssageRequest的message_id属性的映射关系。而请求消息中的revision和sub没有定义在模板中。在实际请求时,通过http请求参数定义:
| HTTP | gRPC |
|---|---|
| GET /v1/messages/123456?revision=2&sub.subfield=foo | GetMessage(message_id: “123456” revision: 2 sub: SubMessage(subfield: “foo”)) |
3. body域
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 | gRPC |
|---|---|
| PATCH /v1/messages/123456 { “text”: “Hi!” } | UpdateMessage(message_id: “123456” message { text: “Hi!” }) |
4. body域取值为*
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 | gRPC |
|---|---|
| PATCH /v1/messages/123456 { “text”: “Hi!” } | UpdateMessage(message_id: “123456” text: “Hi!”) |
三、遇到的问题
很奇怪的是,遇到了一个不知道该怎么写http请求的grpc方法。
gRPC方法定义如下:
rpc Invalidate(InvalidateRequest) returns (Response) {
option (google.api.http) = {
post: "/v1/thing:invalidate"
};
}
message InvalidateRequest{
// Required.
string url= 1 [(validator.field) = {string_not_empty: true}];
// Required. as input.
repeated Message input_messages = 2 [(validator.field) = {repeated_count_min: 1}];
}
message Message {
// Required.
string version = 1;
// Optional.
repeated int64 target_ids = 2;
}
这里的Invalidate方法建立了与http post方法的映射;同时没有提供body域。因此参数都通过url和http查询参数来传递。但。请求方法失败。
猜测: 莫非是构造的input_messages 参数错误?
如有知道的大侠望不吝赐教。
四、总结
本篇主要是介绍了定义gRPC和http方法映射的方法。
本文介绍了gRPC与HTTP方法的映射关系。gRPC是Google基于rpc开发的新功能,可跨语言通信,也能通过HTTP请求访问服务。HttpRule规定了两者的映射规则,包括简单Url模板、请求消息参数处理等。此外,还分享了遇到的问题及总结。
5402

被折叠的 条评论
为什么被折叠?



