Go言語でgRPCを学ぼう~GreetAPI~

こんにちは。KOUKIです。

仕事で、gRPCという通信規格を使っているのですが、これが結構便利なので紹介したいと思います。

Go言語記事まとめ

gRPCとは

gRPCは、Googleが開発したオープンソースのフレームワークで、異なる言語同士で実装されたアプリケーション間で通信を行えるようにできる便利なツールです。

例えば、Pythonで作られたシステムとJavaで作られたシステムがあるとします。

本来であれば、異なる言語で実装されたアプリケーションは言語実装が違うため、そのままでは直接やりとりを行うことはできません。

しかし、gRPCを導入すると言語規格を吸収し、相互のやりとりを可能にするための橋渡しを担ってくれます。

<イメージ>
Python App <———> gRPCのインターフェース <———> Java App

gRPCは、DockerやKubernetesのようなクラウドネイティブ基盤の一部にも使用されており、HTTP2の通信やストリーミングなどもサポートしているので、これからもガンガン使われていくのではないかと思います。

gRPCの始め方

gRPCを使うためにはあらかじめ、「message」と「services」を定義したprotoファイルを用意しておく必要があります。

gRPCは、Protocol Bufferとも呼ばれており、それらを定義するファイルには「.proto」拡張子を付けます。

protoファイルのサンプルを下記に記載します。

現時点では、上記のコードの意味は分からなくて問題ないです。コードを書きながら学んでいきましょう。

プロジェクトの準備

作業用ディレクトリ(プロジェクト)を準備します。

また、grpcのモジュールをインストールしましょう。

次にprotocをダウンロードします。

筆者は、Linuxを使っているので、Linux用のprotocをダウンロードしています。

それを適当なディレクトリに格納し、パスを通します。

筆者は、bashを使っているので、.bashrcに次の一文を書き込んで、パスを通しました。

.bashrcを変更したら忘れずに設定を有効にしましょう。

protoファイルの作成

次にprotoファイルを作成しましょう。

実装場所は、greet.protoです。

protoファイルには、「GreetService」というサービスを定義しました。

このprotoファイルは、あるコマンドでコンパイルしてあげる必要があります。

generate.shに次のコードを記述してください。

このコードを実行してください。

注意) Missing input fileファイルになってしまった場合

シュルを実行した際、「Missing input file」が表示され、コンパイルに失敗しました。

原因は、GOPATHが設定されていなかったことにより、「go get -u github.com/golang/protobuf/protoc-gen-go」で取得したはずのprotoc-gen-goのバイナリファイルが意図しない場所にインストールされていたからでした。

その為、このエラーが出た場合は、GOPATHを設定してみてください。 

GOPATHは、goのソースを取りまとめておく場所を指定する環境変数です。

この環境変数を「~/.bash_profile」に書き込んでおきましょう。

以下のコマンドで、設定を有効にします。

設定が完了したら再度、「protoc-gen-go」をインストールしてみてください。

Serverコードの作成

gRPCでは、ServerコードとClientコードの作成を行います。

まずは、Serverコードから実装していきます。

下記のファイルを作成しましょう。

serverコードには、次の実装を行います。

まず、ポート50051番のポート番号を設定して、リッスンの状態にします。

次に、grpcのNewServer関数にてサーバーを作成し、このサーバーに実行したい処理を登録します。

登録関数は、「RegisterGreetServiceServer」です。

これは、先ほど作成したgreet.pb.goファイルの中に設定されている関数です。

RegisterGreetServiceServer関数の第二引数には、登録したいサービス名を指定するため、$server{}を渡しています。

これから「func (*server) GetCalc() int{ … }」みたいな形で、サービスを登録していきます。

Clientコードの作成

次に、Clientコードを作成します。

Dial関数で、Client Connectionを作成します。

WithInsecureにてセキュアな通信を無効にし、ClientコードからServerコードに対して処理を実行します。

GreetAPI – protoファイルの作成 –

最初のサービスとして、GreetAPIを作成します。

gRPCの通信規格にはいくつか種類があり、今回は「gRPC Unary」を使っていきます。

gRPC Unaryは、一般的な一対一のRequest/Response通信です。

クライアントからサーバーへ単一のリクエストを送り、単一のレスポンスを受け取ります。

少量データの送受信に適している規格ですね。

それでは、protoファイルにgRPC Unaryとメッセージを追加します。

各メッセージの数値は、ただの番号です。メッセージの塊ごとにを上から順に番号を振っていきます。

先頭のGreetingメッセージは、Go言語のStruct宣言みたいなものです。

設定が完了したらコンパイルしましょう。

GreetAPI – Serverコードの作成 –

Serverコードにサービスを実装します。

Greet関数を新しく実装しました。

このGreet関数がどこから出てきたかというと「greet.pb.go」にinterfaceとして実装されています。

このインターフェースを Server Structのメソッドとして実装したわけです。

GetFirstName関数もgreet.pb.goに実装されています。

protoファイルに定義されたメッセージの変数は、このようにgetterメソッドが定義されます。

GreetAPI – Clientコードの作成 –

続いて、Clientコードを実装します。

Clientコードのreq変数に格納している値は、protoファイルに定義したメッセージの内容そのものです。

greet.pb.goにそれぞれStructとして宣言されています。

さて、いよいよ実行してみましょう。

その前に、main.goファイルと同階層にMakefileを作成してください。

ここに実行コマンドを加えます。

Makefileに実行したいコマンドを定義しておけば、コマンド実行がすごく楽になります。※それぞれのコマンド(go run)の先頭はtabでスペースを開ける必要があります

まずは、Serverコードを実行してみましょう。

ターミナルを二つ立ち上げて、片方のターミナル上で下記のコマンドを実行してください。

Hello Worldが出力されたらOKです。

続いて、残りのターミナル上で下記のコマンドを実行してください。

余計な情報も出力されているため分かりずらいですが、「Response from Greet: Hello Harry」が出力されました。

Serverとの通信が正常に行われたようです。

Serverコードを実行しているterminal上でも以下の出力が確認できます。

長くなってきたので、今日はここまでにしましょう。

次回

次回は、Server Streaming APIを使ったAPIを作成します。

参考書籍

コメントを残す