【gRpc】golangでgRpcサーバを立ててみる
今回は以下記事の続きで作成したprotocol buffersによって生成したgolangを使って、実際にgRpcサーバを立ててみようと思います。
【gRpc】Protocol Buffersを使ってgolangソースを生成する
上の記事ではでていたWARNINGを別の記事に書いた方法で解消したので正確には以下記事の続きです。
【gRpc】Protocol Buffersを使ってgolangソースを生成する際のWARNINGを解消
環境情報
OS: Windows10 64bit
golang: v1.15.3
Protocol Buffers: v3.13.0
環境変数「APPS=/c/dev」を設定しています。(アプリの配置先)
※コマンドの実行は基本的にgit bashで行っているのでlinuxコマンドになっています。
サンプルコードのリポジトリ
今回使用したサンプルは以下のリポジトリに配置しています。
https://github.com/i-shinya/grpc-client-server-sample
今回までのサンプルコードは以下のコミットで確認できます。
golangでgRpcサーバを立ててみる
gRpcサーバ用のディレクトリの準備
gRpcサーバ用にディレクトリを用意したいと思います。とりあえずmainを実装するファイルを配置するので以下のようにディレクトリを作成しました。(現在デファクトとなっている構成を元にしています)
.
|-- go-server
| |-- cmd ・・・ (New) 起動コマンドを配置するディレクトリ
| `-- internal ・・・ (New) 複数のアプリ実装を束ねるディレクトリ
| `-- apps ・・・ (New) 今回のサンプルアプリのロジックを実装するディレクトリ
`-- tools
`-- grpc
gRpc Serviceのinterfaceの生成先を変更する
さっそくgRpcサーバを実装したいところですが、先にProtocol Buffersの生成ファイルの配置先を変更したいと思います。前回は以下のコマンドで生成したのでprotoファイルと同一のディレクトリのgrpc-client-server-sample/tools/grpc内の/adapter/gen_grpcに生成されていました。
cd $APPS/grpc-client-server-sample/tools/grpc protoc/bin/protoc --go_out=plugins=grpc:./ protos/*.proto
golangのファイルがtoolsディレクトリに存在するのは気持ち悪いので、今回新たに追加したディレクトリに配置するようにしたいと思います。
.
|-- go-server
|-- cmd
`-- internal
`-- apps ・・・ ここを生成先に指定する
`-- adapter
`-- gen_grpc ・・・ ここに生成される
配置先のディレクトリを変更するために実行コマンドを以下のように変更します。
cd $APPS/grpc-client-server-sample/tools/grpc protoc/bin/protoc --go_out=plugins=grpc:../../go-server/internal/apps/ protos/*.proto
これで配置先が変わったはずです。
go modulesを導入する
golangのパッケージ管理として公式から提供されているgo modulesを導入します。導入は以下のコマンドを実行するのみでOKです。
cd $APPS/grpc-client-server-sample/go-server // go-serverはモジュール名なので任意で変更してください。 go mod init go-server
こちらを実行するとgo.modファイルが作成されるはずです。これで導入完了です。
gRpc用のパッケージをgo getする
gRpcサーバを立てるためのライブラリはgoogleが提供しているgrpc-goを使用します。go.modが配置されているディレクトリで以下を実行すればインストールできます。
go get -u google.golang.org/grpc
Protocol Buffersで生成したServiceの実装を追加
生成したコードはあくまでinterfaceなので実際に使用する際はinterfaceの実装を追加する必要があります。今回は生成されたsample.pb.goの実装をadapterパッケージ配下にimplディレクトリを作成し、こちらにsample_adapter.goを作成し以下のような実装をいれました。(すごく適当です。)
package impl
import (
"context"
pb "go-server/internal/apps/adapter/gen_grpc"
)
type SampleAdapter struct {}
func (s *SampleAdapter) GetMySample(ctx context.Context, message *pb.Sample_GetMySampleMessage) (*pb.Sample_MySampleResponse, error) {
return &pb.Sample_MySampleResponse{
Name: "hogehoge",
Kind: "fugafuga",
}, nil
}
これで実装はOKです!!
gRpcサーバを起動するmainを追加する
ようやく準備が終わりました!それではgRpc起動用のmainを追加します。配置先はgo-server/cmd内でgrpc_main.goというファイル名にしました。
最初はサーバを起動するだけのコードで以下のように書きました。(gRpcのServiceは呼び出せない)
package main
import (
"google.golang.org/grpc"
"log"
"net"
)
func main() {
log.Println("Starting main.")
s := grpc.NewServer()
listener, err := net.Listen("tcp", ":5555")
if err != nil {
log.Fatalln(err)
}
log.Println("Server starting.")
err = s.Serve(listener)
if err != nil {
log.Fatalln(err)
}
}
以下のコマンドを実行すればポート5555でサーバが起動します。
cd $APPS/grpc-client-server-sample/go-server go run cmd/grpc_main.go
ただし、これでは何も実行できないので、gRpcのServiceを使えるようにします。
gRpcのServiceを登録してサーバを実行する
生成したgRpcコードには登録用のメソッドRegisterSampleAdapterServer()が定義されているので、こちらに実装用のStructを渡して登録します。
package main
import (
"go-server/internal/apps/adapter"
pb "go-server/internal/apps/adapter/gen_grpc"
"google.golang.org/grpc"
"log"
"net"
)
func main() {
log.Println("Starting main.")
s := grpc.NewServer()
// gRpcのメソッドを登録する
registerGrpcAdapter(s)
listener, err := net.Listen("tcp", ":5555")
if err != nil {
log.Fatalln(err)
}
log.Println("Server starting.")
err = s.Serve(listener)
if err != nil {
log.Fatalln(err)
}
}
// gRpcで生成したadapterを登録する
// gRpc Serviceを追加した場合はここに記載を追加していく
func registerGrpcAdapter(s *grpc.Server) {
// SampleAdapterを登録する
pb.RegisterSampleAdapterServer(s, &adapter.SampleAdapter{})
}
これでサンプルとして実装した処理を行えます。早速以下の記事で紹介したgRpc用のテストクライアント「Bloom RPC」を使用して動作確認してみます。
【gRpc】シンプルなgRpc用のテストクライアントツール「BloomRPC」の紹介
動作確認する
再びサーバを起動した状態でBloom RPCを起動し、Sample.protoを読み込んで実行してみます。

ちゃんとhogehogeとfugafugaが返ってきました!(適当すぎる・・・)
今回はこれにて終了です。記事書くの疲れた・・・。
参考
https://qiita.com/marnie_ms4/items/4582a1a0db363fe246f3

ディスカッション
コメント一覧
まだ、コメントがありません