proto編譯組件使用


proto編譯組件使用

前提:所有組件已經安裝好,包括:

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;

1. 編譯pb.go文件

需要使用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文件。

2. 編譯pb.gw.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

3. 編譯swagger.json文件

需要使用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文件。

4. 總結

至此,三個文件都已經成功生成了,整理下目錄文件,如下:

.
├── hello.pb.go
├── hello.pb.gw.go
├── hello.proto
└── hello.swagger.json

其中踩了好幾個坑:

  • google/api/annotations.proto怎么解決
  • proto引入外部proto文件怎么處理
  • gateway生成失敗報錯

雖然還有些地方沒弄清楚,但好歹都解決了,記錄一下供學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM