在第一篇: Go GRPC 实战入门 01: 从 proto 到 rpc 中我已经介绍了如果从零到编写 Proto 文件,然后跟根据 Proto 文件生成 GO 语言的脚手架,并且编写客户端和服务端的过程。虽然这整个过程没啥大问题,服务端和客户端都是可以正常工作的,但是,在真实生产环境中却不一定适用,当然,当你一切都是从零开始的时候,你可能可以一切都是 GRPC,甚至连 Web 客户端都通过 GRPC 进行调用;但是,如果你是一个有底蕴的公司,有一些历史包袱的话,那么可能就不那么美好了,你可能需要兼容一些老的格式,例如 REST 风格的 API,设置更老一些的 Web Service,或者更陈旧一些的通用协议等等,我可能兼顾不了这么多,所以这篇文章就从可能稍微现代一些的 REST 风格的 API 兼容先来说说吧。

还是前面的老梗,当然,你可以自己实现一个 REST Server 用来适配 GRPC,但是,作为一个被广泛使用的 RPC 协议,GRPC 有一些可以帮助我们快速进行协议转换的工具,这里我要所的就是:grpc-gateway

先来看下这个工具的情况,在官方介绍中是这样的:

通过一份 Proto,我们生成两种代码,一种是提供 REST 风格 API 的脚手架,另外一个就是我们在第一篇中看过的 Go 的 GRPC 脚手架,OK,对于生成 GRPC 的脚手架我们在第一篇中已经介绍过了,那么怎么生成 REST 风格 API 的脚手架呢?这是我们要解决的第一个问题,让我们从官方的文档中学习一下。

第一步还是和第一篇一样,需要安装工具,虽然从官方介绍中需要安装三个工具,实际上我们只需要安装一个,因为第二个不是必须的,第三个我们已经安装过了:

  1. $ go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
  2. $ go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
  3. $ go get -u github.com/golang/protobuf/protoc-gen-go

第二步我们什么都别说,先执行一下命令看看什么效果:

  1. $ protoc -I/usr/local/include -I. \
  2. -I$GOPATH/src \
  3. -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
  4. --grpc-gateway_out=logtostderr=true:go \
  5. protos/helloworld.proto

这里一敲下去,居然没报错,然后我们去看下生成的代码,然后你会发现没有生成代码,这是为什么呢?原来这里 grpc-gateway 是作为一种扩展来扩充 GRPC 的功能,在第一篇的时候我们说过定义操作的时候为什么要以 {} 结尾,这里就用到了这个功能,我们做 proto 文件进行一个修改:

这里我做了一个扩充,然后再执行一遍命令:

  1. $ protoc -I/usr/local/include -I. \
  2. -I$GOPATH/src \
  3. -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
  4. --grpc-gateway_out=logtostderr=true:go \
  5. protos/helloworld.proto

然后你会发现在 go/protos 目录下生成了一份: helloworld.pb.gw.go,然后我们稍微看一下里面的内容:

可以大体上看出这是一个帮助我们请求 GRPC 服务端的响应并且转换给客户端的一个操作。那么当我们有了这份脚手架之后又要怎么使用呢,我这里也给出了一个实现:rest/main.go

然后运行起来,尝试访问一下看看:

这样,我们就以 REST 形式运行起我们的服务端了,也可以满足使用 HTTP/1.1 的方式来访问我们的业务了。