社区编辑申请
注册/登录
Golang用Proto文件同时生成gRPC和HTTP
开发 前端
为了避免需要分别编写两套契约文件来生成两套 API(.proto 和 .api),如果能够根据同一份契约文件生成两套 API 的代码就太棒了。

大家好,我是Z哥。

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

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

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

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

https://github.com/grpc-ecosystem/grpc-gateway

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

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

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

1.不会科学上网不要用buf

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

2.手动下载 googleapis 的repo

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

https://github.com/googleapis/googleapis

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

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

https://github.com/protocolbuffers/protobuf/tree/main/src/google/protobuf

3.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的其它用法可以参考:

https://grpc-ecosystem.github.io/grpc-gateway/

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

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

责任编辑:武晓燕 来源: 跨界架构师
相关推荐

2022-02-20 23:15:46

gRPCGolang语言

2021-12-05 23:14:24

2021-09-13 05:02:49

2021-04-26 09:49:46

服务设计消息

2021-09-26 10:20:06

2022-04-12 11:46:08

服务gRPC反向代理

2021-08-03 09:07:39

2021-09-01 23:29:37

同话题下的热门内容

Java 服务 Docker 容器化优秀实践程序员不得不知道的 API 接口常识TestOps完全手册:工作流、生命周期、团队和流程11个 ES2022(ES13)中惊人的 JavaScript 新特性不要在 Python 中使用循环,这些方法其实更棒!使用 Vite 和 TypeScript 带你从零打造一个属于自己的 Vue3 组件库你需要知道的TypeScript高级类型Hooks时代,如何写出高质量的react和vue组件?

编辑推荐

太厉害了,终于有人能把TCP/IP协议讲的明明白白了!牛人5次面试腾讯不成功的经验HBase原理–所有Region切分的细节都在这里了Javascript如何监听页面刷新和关闭事件如何搭建一个HTTPS服务端
我收藏的内容
点赞
收藏

51CTO技术栈公众号