七叶笔记 » golang编程 » Golang用proto文件同时生成gRPC和HTTP

Golang用proto文件同时生成gRPC和HTTP

大家好,我是Z哥。

做技术的都知道,程序之间的通讯,常用的方式有两种,RPC 和 HTTP。普遍的共识是系统内部的各个子系统之间的通讯用 RPC,与外部系统之间的通讯用 HTTP。

为了避免需要分别编写两套契约文件来生成两套 API(.proto 和 .api),如果能够根据同一份契约文件生成两套 API 的代码就太棒了。

Z哥目前所在的公司,rpc 使用的框架是 gRPC,所以自然先想得是,是否能够根据一份 proto 文件,同时生成 gRPC 和 HTTP 的 stub 代码呢。

网上很快就找到了一个符合要求的框架。相信不少 gopher 们应该也听说过或者正在使用。

框架的原理用一张图即可表达。

通过一份 proto 文件,在生成 gRPC 代码的同时生成一个基于 HTTP1.1 + JSON 的反向代理 gateway,如此一来,既可以通过 gRPC 的方式直接调用实际的 server ,也可以通过反向代理中转一次来访问 server。

具体的使用方式看 github 上的官方教程即可,Z 哥和你主要聊一下其中可能会遇到的卡点。毕竟国内的网络情况你懂的,有些操作可能会遇到一些困难。

/01 不会科学上网不要用buf/

教程里提供了两种来操作,一种是通过基础工具 protoc 来操作,另一种是通过一个基于 protoc 封装的工具 buf 来操作。protoc 可以基于 go mod 来安装,鉴于 go mod 还有国内的镜像站点可以解决访问的困难,建议不会科学上网的小伙伴通过 protoc 来操作,因为你没办法成功安装 buf。

/02 手动下载 googleapis 的repo/

然后,当你定义 gateway 的时候,需要引入一些 google 的 packages,怎么办呢?直接去 github 上下载,具体地址是:

如果可以的话,建议把整个仓库都下载下来,否则就单独下载教程里提到的4个文件即可。

特别要注意的是,在 googleapis/google/目录下缺少的 protobuf 相关文件需要到下面的 repo 里去下载,并且放到 googleapis/google/目录下。

/03 protoc -I 指定查找目录/

官方教程里的 protoc -I . 只会查找当前命令执行所在目录的范围,所以如果你下载的 googlesapi 不存放在当前目录下,则需要增加额外信息指定一下查找目录。

指定的方式是再增加一个 -I,命令如下(其中第二行就是新增的用于查找 google packages 的目录):

 protoc -I ./ \
    -I $GOPATH/src/googleapis\
    --grpc-gateway_out ./gen/go \
    --grpc-gateway_opt logtostderr=true \
    --grpc-gateway_opt paths=source_relative \
    --grpc-gateway_opt generate_unbound_methods=true \
    your/service/v1/your_service.proto  

如果还有其它目录需要查找,那么继续增加 -I 即可。

好了需要注意的点就是以上3个,官方教程中提到的三个命令可以一起执行,这样便可同时生成 gRPC server、gateway 和 swagger.json :

 protoc -I ./ \
    -I $GOPATH/src/googleapis\
    --go_out ./gen/go/ --go_opt paths=source_relative \
    --go-grpc_out ./gen/go/ --go-grpc_opt paths=source_relative \
    --grpc-gateway_out ./gen/go/  \
    --grpc-gateway_opt logtostderr=true \
    --grpc-gateway_opt paths=source_relative \
    --grpc-gateway_opt generate_unbound_methods=true \
    --openapiv2_out . --openapiv2_opt logtostderr=true \
    your/service/v1/your_service.proto  

关于一些gRPC-Gateway的其它用法可以参考:

好了,这篇呢,Z哥和你分享了如何用一份 proto 文件同时生成 gRPC 和 HTTP 的 Stub 代码以及 Swagger 文档。

如此不但可以提高效率,还可以避免维护两份不同的契约文件所带来不一致风险,希望对你有所帮助。

推荐阅读:


也可以「关注」我,带你以技术思维看世界~

想更进一步和我一起玩耍,欢迎「搜索微信公号:跨界架构师」。

内容包括:架构设计丨分布式系统丨产品丨运营丨个人深度思考。

相关文章