GolangでgRPC使ってみた
ほとんど公式のQuickStartのまんまだけど、一応備忘録
gRPCとは
gRPC は、Protocol Buffers を使ってデータをシリアライズし、高速な通信を実現できるRPCフレームワーク(Google謹製)。
セットアップ
- Install gRPC
go get -u google.golang.org/grpc
- Install protobuf for Mac
brew install protobuf
- Install protocol buffers lib for Golang
go get -u github.com/golang/protobuf/protoc-gen-go
.protoファイルを実装する
ドキュメントを参考にインターフェースを定義する。
何も考えずにミニマムでメソッドを作ってみた。
syntax = "proto3"; package proto; service Test { rpc Get (Request) returns (Response); } message Request { string Message = 1; } message Response { string Message = 1; }
.protoファイルから.goファイルを生成する
protoc
コマンドを使って.proto
ファイルから.go
ファイルを生成する。
protoc -I proto/ proto/*.proto --go_out=plugins=grpc:proto
goのインターフェースが定義されたtest.pb.go
ファイルが作成されているはず。
サーバーサイドプログラミング
何も考えずにtest.pb.go
ファイルに定義されているインターフェースを実装し、
ポート50051でリッスンする。
package main import ( "context" "net" pb "github.com/yuki-toida/grpc-sample/proto" "google.golang.org/grpc" ) func main() { listener, err := net.Listen("tcp", ":50051") if err != nil { panic(err) } server := grpc.NewServer() pb.RegisterTestServer(server, &Server{}) server.Serve(listener) } type Server struct{} func (s *Server) Get(c context.Context, r *pb.Request) (*pb.Response, error) { return &pb.Response{Message: r.Message}, nil }
クライアントサイドプログラミング
ポート50051でリッスンされているサーバーに接続するクライアントを実装する。
この例では、コマンドラインパラメータを受け取りそのまま標準出力される。
package main import ( "context" "fmt" "os" "time" pb "github.com/yuki-toida/grpc-sample/proto" "google.golang.org/grpc" ) func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { panic(err) } defer conn.Close() ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() message := "Hello" if 1 < len(os.Args) { message = os.Args[1] } client := pb.NewTestClient(conn) res, err := client.Get(ctx, &pb.Request{Message: message}) if err != nil { panic(err) } fmt.Println(res) }
大規模開発におけるDDD時、gRPC
のインターフェースをどの層に依存させるか悩みそう。
素直にユーザーインターフェース層かな、そうするとすごく膨れ上がりそうな気配がする。