AppEngine Standard Environmentでgrpc-gatewayが使いたいので、なんとかした
AppEngineでgRPCを使う場合 ClientはTCP Socketが使えるので問題ないんですが、Serverに関してはFlexible Enviromentを利用しなければ利用できないのでなんとかStandard Enviromentで とりあえず 使う方法のメモ
gRPCを使いたい理由
そもそもなんでgRPCが使いたいかというと
APIを作るときにサーバーを作ったらそれに合わせてクライアントを実装するというのがよくとられる開発スタイルだと思うのですが
開発が進むに連れてサーバーとクライアントにズレが出てきてしまうことがあるかもしれません
それを防ぐのに一番いい方法はサーバー作る人がクライアントも一緒に作ることなんですが
それはそれでサーバーをやる人の負担が増えるので
サーバーを実装したらクライアントを自動生成するのが理想だなと思ったためです。
gRPCは色んな言語のクライアントを自動生成してくれるので便利で
同じ様な物でswaggerがありますが、swaggerの定義ファイルは人間が書くものではなかったためgRPCをベースにしたいと思いました。
あとAppEngineがgRPCに対応することがあったらすぐ切り替えれるようにするためです。
環境
go: 1.6
appengine: 1.9.37
で試してます。
またJSONに変換する部分はgrpc-gatewayを利用します。
grpc-gatewayはgRPC clientを内包するJSON serverで
gRPC Serverの中継用のサーバです。
また swaggerの定義ファイルを生成できるので
クライアントの自動生成はswaggerを使います。
必要なツールとパッケージ
go get -u github.com/golang/protobuf/protoc-gen-go
go get -u github.com/gengo/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/gengo/grpc-gateway/protoc-gen-swagger
go get -u github.com/k2wanko/grpc-pipe
定義
以下の様な単純にメッセージを返すだけのサービスを作るとします。
syntax = "proto3";
option go_package = "echo";
// Echo Service
//
// Echo Service API consists of a single service which returns
// a message.
package echo;
// SimpleMessage represents a simple message sent to the Echo service.
message Message {
string value = 1;
}
// Echo service responds to incoming echo requests.
service EchoService {
// Echo method receives a simple message and returns it.
//
// The message posted as the id parameter will also be
// returned.
rpc Echo(Message) returns (Message);
}
以下のコマンドでサーバーのinterfaceとclientを作成します。
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/gengo/grpc-gateway/third_party/googleapis \
--swagger_out=logtostderr=true:. \
--grpc-gateway_out=logtostderr=true:. \
--go_out=Mgoogle/api/annotations.proto=github.com/gengo/grpc-gateway/third_party/googleapis/google/api,plugins=grpc:. \
echo_service.proto
実装
AppEngineで使うための実装です。
type echo struct{}
func (*echo) Echo(ctx context.Context, m *pb.Message) (*pb.Message, error) {
return m, nil
}
import(
...
"github.com/k2wanko/grpc-pipe/gateway"
pb "./echo"
)
func init() {
s := gateway.New(context.Background())
s.RegisterService(pb.RegisterEchoServiceServer, pb.RegisterEchoServiceHandler, new(echo))
http.Handle("/", s)
}
goapp serve
コマンドで起動してhttp://localhost:8080/echo
にcurlで叩きます
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"value":"Hi"}' http://localhost:8080/echo
完全なサンプルはgithubにあります。
SwaggerUIとappengine.NewContext
を挟むサンプルにもなってるのでAppEngineのサービスも利用できます。
grpc-pipeの仕組み
grpc-pipeが何をやってるかというと
単純にnet.Pipe
を使ってメモリ内でクライアントとサーバーを繋いでます
なのでオーバーヘッドが気になります。
まとめ
ちゃんとgenerator書いて直接サーバーの実装を呼び出せるようにしようと思ってるので
時間が空いたらやってみます
Author And Source
この問題について(AppEngine Standard Environmentでgrpc-gatewayが使いたいので、なんとかした), 我々は、より多くの情報をここで見つけました https://qiita.com/koki_cheese/items/0e89ab7f023634c6838f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .