Goのプロジェクト内でgRPCで自分で定義したprotoファイルをimportする
自分で作ったprotoファイルを他のprotoファイルから参照する時にハマったのでメモ
サンプルプロジェクトの構成
. ├── Makefile ├── team │ └── handler │ └── grpc │ └── team │ ├── team.pb.go │ └── team.proto └── user └── handler └── grpc └── user ├── user.pb.go └── user.proto 8 directories, 5 files
構成はクリーンアーキテクチャライクにしています
proto ファイル
userから
syntax = "proto3"; package user; service UserAPI { rpc GetUsers(User) returns (Users) {} rpc Show(User) returns (User) {} rpc Delete(User) returns (Empty) {} rpc Invite(User) returns (Empty) {} rpc Activate(ActivateRequest) returns (ActivateResponse) {} } message User { int64 id = 1; int64 team_id = 2; string name = 3; string email = 4; string password = 5; bool isOwner = 8; } message ActivateRequest { string code = 1; } message ActivateResponse { string token = 1; } message Users { repeated User Users = 1; } message Empty {}
普通のprotoファイルです
次はteam
syntax = "proto3"; package team; import "github.com/Bo0km4n/go-protobuf-ref-sample/user/handler/grpc/user/user.proto"; service TeamAPI { } message Team { int64 id = 1; string name = 2; user.Users users = 3; } message InviteRequest { string team = 1; string email = 2; string password = 3; } message ActivateRequest { string code = 1; } message ActivateResponse { string token = 1; } message Empty {}
userを内部で参照しています。
コンパイル
最初は以下のページを参考にコンパイルを行っていましたが生成されるpbファイルのimportパスが相対パスになっており go build
時に参照できません
そこで上記のように github.com/...
のように通常のgoのimportパスと同様にすることでこの問題を解決します
ビルドに使用するmakefileをつぎのように書きました
PROTO_TARGETS = user team PROJECT_PATH = github.com/Bo0km4n/go-protobuf-ref-sample proto: @echo $(PROTO_TARGETS); \ cd $$GOPATH/src; \ for t in $(PROTO_TARGETS); do \ echo "protobuf build ... $$t"; \ protoc --go_out=plugins=grpc:. $(PROJECT_PATH)/$$t/handler/grpc/$$t/$$t.proto; \ done
最初にechoしているのはしないと cd
のせいなのか Nothing to done
って言われるからです
上記のリンクではプロジェクトのルート以下のパスが生成されるimportパスになっていました。
つまり、$GOPATH/src
で上記のビルドを行えば生成されるimportパスが正常になります。
実際に生成されたteamのpbファイルは次のようになります
// Code generated by protoc-gen-go. DO NOT EDIT. // source: github.com/Bo0km4n/go-protobuf-ref-sample/team/handler/grpc/team/team.proto package team import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" import user "github.com/Bo0km4n/go-protobuf-ref-sample/user/handler/grpc/user" import ( context "golang.org/x/net/context" grpc "google.golang.org/grpc" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type Team struct { Id int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Users *user.Users `protobuf:"bytes,3,opt,name=users" json:"users,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` } ... 以下省略
これでプロジェクトのビルドも上手くいきます
$GOPATH/src に移動するのは少々スマートではない気がしますが色々調べて他に良いやり方がなかったので今回は妥協しました
一応今回のサンプルをgithubにあげておきます