Protobuf
(全称Protocol Buffer
)是Google
出品的一种数据描述语言,可类比于json
,独立于语言与平台。
Protobuf
提供了多种语言的实现:java
、c#
、c++
、go
和 python
,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,总得来说就是更小、更快、更简单、更灵活,目前分别有v2
、v3
的版本,我们推荐使用v3
。具体查看Protocol Buffers
的README介绍。
protoc
是.proto
文件的编译器(参见github),可以借助这个工具把.proto
文件转译成各种编程语言对应的源码,包含数据类型定义、调用接口等。
通过查看protoc
的源码可以知道,protoc
在设计上把Protobuf
和不同的语言解耦了,底层用c++
来实现Protobuf
结构的存储,然后通过插件的形式来生成不同语言的源码。可以把protoc
的编译过程分成简单的两个步骤(如上图所示):
.proto
文件,转译成protobuf
的原生数据结构在内存中保存;protobuf
相关的数据结构传递给相应语言的编译插件,由插件负责根据接收到的protobuf
原生结构渲染输出特定语言的模板。protoc
源码中直接包含的插件有 csharp
、java
、js
、objectivec
、php
、python
、ruby
等多种(没有直接提供给go)。
protoc
的go
插件版本有两个,第一个主要版本(于2010年公开发布)由github.com/golang/protobuf
模块实现;第二个主要版本(于2020年发布)则是由google.golang.org/protobuf
模块实现。
protoc-gen-go
是protobuf
编译插件系列中的Go
版本,执行下面的任一命令即可安装到$GOPATH/bin
目录下
go get -u github.com/golang/protobuf/protoc-gen-go # v1
go get -u google.golang.org/protobuf/cmd/protoc-gen-go # v2,建议使用
虽然protoc-gen-go
是二进制文件,但不能直接使用,protoc
编译时使用-go_out
选项,protoc
会自动寻找PATH
(系统执行路径)中的protoc-gen-go
文件,从而生成*.pb.go
文件,示例如下:
# 当前目录编译 helloworld.proto 生成 helloworld.pb.go
protoc -I . --go_out . --go_opt paths=source_relative ./helloworld.proto
protoc-gen-go-grpc
是go
版本的grpc
编译插件,用于读取.proto
文件中的grpc
服务定义生成特定的go
代码,具体参见github
。同protoc-gen-go
一样,protoc-gen-go-grpc
也是由protoc
驱动使用的,示例如下
# 当前目录编译 helloworld.proto 生成 helloworld.pb.go 和 helloworld_grpc.pb.go
protoc -I . -I $GOPATH/src/github.com/googleapis/googleapis/ \
--go_out . --go_opt paths=source_relative \
--go-grpc_out . --go-grpc_opt paths=source_relative \
./helloworld.proto
protoc-gen-grpc-gateway
也是go
版本的grpc
编译插件,与protoc-gen-go-grpc
不同的是,该插件用于读取gRPC
服务定义,生成一个反向代理服务器,将RESTful JSON API
转换为gRPC
。此服务器是根据gRPC
定义中的自定义选项生成的。
使用示例如下:
# 当前目录编译 helloworld.proto 生成 helloworld.pb.go、helloworld_grpc.pb.go 和 helloworld.gw.pb.go
protoc -I . -I $GOPATH/src/github.com/googleapis/googleapis/ \
--go_out . --go_opt paths=source_relative \
--go-grpc_out . --go-grpc_opt paths=source_relative \
--grpc-gateway_out . --grpc-gateway_opt paths=source_relative \
./helloworld.proto
首先介绍下Swagger
,Swagger
是全球最大的OpenAPI
规范(OAS)API开发工具框架,支持从设计和文档到测试和部署的整个API生命周期的开发,是目前最受欢迎的RESTful Api
文档生成工具之一。
protoc-gen-swagger
是grpc-gateway
的Swagger
工具,可用于生成你的grpc
服务的RESTful Api
文档。
# 当前目录编译 helloworld.proto 生成 helloworld.pb.go、helloworld_grpc.pb.go、helloworld.gw.pb.go 和 helloworld.swagger.json
protoc -I . -I $GOPATH/src/github.com/googleapis/googleapis/ \
--go_out . --go_opt paths=source_relative \
--go-grpc_out . --go-grpc_opt paths=source_relative \
--grpc-gateway_out . --grpc-gateway_opt paths=source_relative \
--swagger_out=logtostderr=true:. \
./helloworld.proto
目前,grpc-gateway V2
已经发布,同时protoc-gen-swagger
改名为protoc-gen-openapiv2
生成 restful api 文档参考 swagger ui
插件 | 描述 | 功能 | 源码仓库 |
---|---|---|---|
protoc | .proto 文件编译器 | 读取.proto 文件中的数据结构传递给相应的编译插件 | github |
protoc-gen-go | go 版本的protoc 编译插件 | 读取.proto 文件的message 数据定义生成*.pb.go 文件 | github v1版本 github v2版本 |
protoc-gen-go-grpc | go 版本grpc 的protoc 编译插件 | 读取.proto 文件的grpc 服务定义生成*_grpc.pb.go 文件 | github |
protoc-gen-grpc-gateway | go 版本grpc 反向代理的protoc 编译插件 | 读取.proto 文件的grpc 服务定义生成*.gw.pb.go 文件 | github |
protoc-gen-swagger | go 版本grpc v1 的restful api 文档生成工具, | 用于生成你的grpc 服务的RESTful Api 文档 | github |
protoc-gen-openapiv2 | go 版本grpc v2 的restful api 文档生成工具 | 用于生成你的grpc 服务的RESTful Api 文档 | github |
该存储库是Google proto buffer
的源码库,包含protoc buffer
编译器protoc
和多种语言的proto buffer
编译插件的实现。
该存储库是protoc buffer
的go
版本实现,protoc-gen-go
目录即编译插件protoc-gen-go
的实现。
实际上,go
实现了两个主版本 (major version
) 的protoc buffer
,该存储库便是第一版,第二版是google.golang.org/protobuf
,该库包含更新的简化的API,支持protobuf
反射以及许多其他改进。 建议新代码使用google.golang.org/protouf
模块。
另外第一版有一个增强版,参见github.com/gogo/protobuf
。
该存储库是github.com/golang/protobuf
的增强版,生成的编译插件为protoc-gen-gofast
,兼容github.com/golang/protobuf
,具有更快的序列化与反序列化速度,支持更多的go
结构规范。
另外,该存储库还可以生成以下几个更高效的编译插件:
protoc-gen-gogofast (same as gofast, but imports gogoprotobuf)
protoc-gen-gogofaster (same as gogofast, without XXX_unrecognized, less pointer fields)
protoc-gen-gogoslick (same as gogofaster, but with generated string, gostring and equal methods)
Fields without pointers cause less time in the garbage collector. More code generation results in more convenient methods.
该存储库包含支持REST
和gRPC
协议的公共Google API
的原始接口定义。即各种googleapi
的proto
文件,比如目录 google/api
下的annotations.proto
。
github.com/golang/protobuf
的v1.4
及更高版本是根据google.golang.org/protobuf
实现的。 使用这两个模块的程序必须至少使用该模块的v1.4版本。
该存储库包含常见protocol buffer
类型生成的Go
代码库,以及与Google gRPC API
进行交互所必需的生成的gRPC
代码。
其中,googleapis
目录是根据github.com/googleapis/googleapis
生成的go
代码。protobuf
目录则 github.com/google/protobuf
下常用类型的生成代码。
该存储库是go
实现的第二个主版本的protoc buffer
,代码托管在github
。主要包含两个部分:
protoc-gen-go
: protoc
的go
编译插件,用于生成特定的go
代码;Runtime library
: 该模块包含一组Go
软件包,这些软件包构成了Go中protobuf
的运行时实现,提供了一组消息定义接口,以及序列化各种消息格式 (比如 json
、text
、wire
) 的功能。该存储库是go
版本的grpc
实现,提供了protoc-gen-go-grpc
编译插件。源存储库为google.golang.org/grpc
。
该存储库是go
版本的grpc-gateway
实现,用于读取gRPC
服务定义,生成一个反向代理服务器,将RESTful JSON API
转换为gRPC
。此服务器是根据gRPC
定义中的自定义选项生成的。为此,该存储库提供了protoc-gen-grpc-gateway
和protoc-gen-openapiv2
两个编译插件。