前提:所有组件已经安装好,包括:
protoc protoc-gen-go protoc-gen-grpc-gateway protoc-gen-swagger
怎么装再开一篇
分为三个部分:
编译pb.go
编译pb.gw.go
编译swagger.json
首先准备hello.proto
文件:
syntax = "proto3"; package hello; import "google/api/annotations.proto"; service HelloWorld { rpc SayHelloWorld(HelloWorldRequest) returns (HelloWorldResponse) { option (google.api.http) = { post: "/hello_world" body: "*" }; } } message HelloWorldRequest { string referer = 1; } message HelloWorldResponse { string message = 1;
需要使用protoc-gen-go
组件,命令:
protoc --go_out=plugins=grpc:. ${xxx.proto}
注意要用-I
参数引入相关的依赖,例如这里的google/api/annotations.proto
:
protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --go_out=plugins=grpc:.
第一个-I
引入当前目录(因为要用hello.proto
);
第二个-I
引入go的相关依赖;
第三个-I
引入annotations.proto
这个文件,使用的前提是$GOPATN/src
下已经准备好了相关的包;
完整命令:
protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --go_out=plugins=grpc:. ./hello.proto
输出:
$ protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --go_out=plugins=grpc:. ./hello.proto protoc-gen-go: unable to determine Go import path for "hello.proto" Please specify either: • a "go_package" option in the .proto source file, or • a "M" argument on the command line. See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information. --go_out: protoc-gen-go: Plugin failed with status code 1.
看输出需要在hello.proto
文件中指定go_package
参数,这里设置为当前目录,更新下hello.proto
内容:
syntax = "proto3"; package hello; option go_package="./"; import "google/api/annotations.proto"; service HelloWorld { rpc SayHelloWorld(HelloWorldRequest) returns (HelloWorldResponse) { option (google.api.http) = { post: "/hello_world" body: "*" }; } } message HelloWorldRequest { string referer = 1; } message HelloWorldResponse { string message = 1; }
再次编译,成功生成hello.pb.go
文件。
需要使用protoc-gen-grpc-gateway
组件,命令:
protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --grpc-gateway_out=logtostderr=true:.
运行:
protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --grpc-gateway_out=logtostderr=true:. ./hello.proto
这时候命令行会输出一大串东西,生成文件失败,并且在最后标注了:
... --grpc-gateway_out: 11:1: expected 'IDENT', found 'import'
试了很多方法,最后发现,go_package
参数不能写./
,要加上后缀包名,例如改成./hello
,不知道真正的原因是不是这个,但这样改了以后编译通过了。
这时候完整的hello.proto
如下:
syntax = "proto3"; package hello; option go_package="./hello"; import "google/api/annotations.proto"; service HelloWorld { rpc SayHelloWorld(HelloWorldRequest) returns (HelloWorldResponse) { option (google.api.http) = { post: "/hello_world" body: "*" }; } } message HelloWorldRequest { string referer = 1; } message HelloWorldResponse { string message = 1; }
重新运行上面的命令,成功生成 hello.pb.gw.go
文件,此时目录如下:
. ├── hello │ └── hello.pb.gw.go ├── hello.pb.go └── hello.proto
需要使用protoc-gen-swagger
组件,命令:
protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --swagger_out=logtostderr=true:.
运行:
protoc -I ./ -I $GOPATH/src -I $GOPATH/src/google/api --swagger_out=logtostderr=true:. ./hello.proto
变成成功,生成hello.swagger.json
文件。
至此,三个文件都已经成功生成了,整理下目录文件,如下:
. ├── hello.pb.go ├── hello.pb.gw.go ├── hello.proto └── hello.swagger.json
其中踩了好几个坑:
google/api/annotations.proto
怎么解决虽然还有些地方没弄清楚,但好歹都解决了,记录一下供学习。