02. November 2021
用Protobuf定义RPC和HTTP服务
plugins
插件 | 功能 | 版本 | 备注 |
---|---|---|---|
protoc | 调用编译程序 | v3.17.3 | |
protoc-gen-go | 编译message结构体 | - | |
protoc-gen-go-grpc | 编译grpc接口 | v1.0.1 | |
protoc-gen-grpc-gateway | 编程http接口 | - | |
protoc-gen-swagger | 生成swagger文档 | - | |
protoc-gen-validate | 生成validate格式校验 | v0.6.2 | #570 |
sample
1
2syntax = "proto3";
3
4package message;
5option go_package = "/;gen";
6
7import "google/api/annotations.proto";
8
9service Serv {
10 rpc SayHelloWorld (request) returns (response) {
11 option (google.api.http) = {
12 get: "/helloworld"
13 };
14 };
15}
16
17message request {}
18
19message response {
20 string raw = 1;
21}
go_package
go_package
指定生成的go文件的包名,选项的值分为两部分,分号之前表示生成文件的路径,路径的/
根目录是指protoc
编译时选项--go_out
指定的位置,分号之后的第二部分表示生成文件的包名
package
package
表示当前proto文件的包
import
google/api/annotations.proto
是编译http接口必须依赖的文件,引用了这个文件直接编译会出现错误,因为protoc
找不到这个文件的位置,import
的包位置是从根目录开始的文件位置,这里的根目录是指$GOPATH/src
所在的路径,解决的方法有两种,可以把文件拷贝到对应位置,也可以用protoc
的选项来添加可选根目录的位置,他是一个数组,通过--proto_path
可以指定根目录的位置,如果想指定多个位置,用:
分隔开就可以了,像PATH
一样,这个选项的设置是覆盖的,如果使用,必须指定出所有需要的位置
build
1PROTO_SRC=./gen.proto
2
3message:
4 protoc --go_out=. --proto_path=.:$$GOPATH/src:$$GOPATH/src/github.com/googleapis/googleapis $(PROTO_SRC)
5
6grpc:
7 protoc --go-grpc_out=require_unimplemented_servers=false:. --proto_path=.:$$GOPATH/src:$$GOPATH/src/github.com/googleapis/googleapis $(PROTO_SRC)
8
9gateway:
10 protoc --grpc-gateway_out=. --proto_path=.:$$GOPATH/src:$$GOPATH/src/github.com/googleapis/googleapis $(PROTO_SRC)
11
12swagger:
13 protoc --swagger_out=. --proto_path=.:$$GOPATH/src:$$GOPATH/src/github.com/googleapis/googleapis $(PROTO_SRC)
14
15validate:
16 protoc --validate_out=lang=go:$(OUT_ROOT_PATH) --proto_path=.:$$GOPATH/src:$$GOPATH/src/github.com/googleapis/googleapis $(PROTO_SRC)
17
18.PHONY: message grpc gateway swagger validate
require_unimplemented_servers=false
新版本的protoc-gen-go
移除了生成grpc
代码的功能,生成grpc
功能独立成为一个工具protoc-gen-go-grpc
,在v1.0.0
和v1.1.0
上通过默认方式产生的grpc
代码都会包含一个无法实现的接口mustEmbedUnimplementedServServer
,通过require_unimplemented_servers=false
可以阻止生成这个接口,原因得看这里