サンプルアプリケーション
前回までの記事の内容でDartとJavaのインターフェイスとなるパッケージをそれぞれ作成し、それに対して実際のアプリケーションから依存関係を持てるようになりました。
クライアント
まずはこれを利用したFlutterのアプリケーションです。
次のリポジトリで管理しています。
実際にiOSシミュレーターで動かしている様子です。

「send」というボタンを押すと、テキストフィードに入力された文字列がJavaのgRPCサーバーに送られ、応答された文字列をボタンの下に出力する簡単なアプリケーションです。
インターフェイスとなるDartパッケージに依存関係を記述しているpubspec.yamlは以下の箇所です。
コードでポイントとなるのは、自動生成された「EchoServiceClient」を利用し、GetItでシングルトンとして管理している以下の箇所でしょうか。
「send」ボタンが押されたら、以下の箇所で「EchoServiceClient」を取得して、サーバーからの応答をawaitしています。
サーバーから応答されたメッセージを表示させるための状態管理には「fluter_riverpod」のStateProviderとConsumerWidgetを使っています。
サーバー
次にJavaのgRPCサーバーは、「Spring initializr」で雛形を作成し、次のリポジトリで管理しています。
インターフェイスとなるJavaパッケージに依存関係を記述しているbuild.gradleは以下の箇所です。
環境変数「GITHUB_USER」と「GITHUB_TOKEN」は予め自分のものを設定しています。
Gradleで「bootRun」が使えるようにプラグインが設定されており、今回はアノテーションベースでgRPCサーバーのコードを記述することができる「grpc-spring-boot-starter」を利用させて頂いています。
応答を返すサーバーのコードは、自動生成されたコードを利用しているため、次のように非常にシンプルです。
クライアントから届いたメッセージの文字数をカウントして、メッセージの末尾に付与して返しています。
今回は「6848」番のポートでgRPCサーバーが応答するように作成していますが、これは次のように「application.yml」で定義しています。
サーバーの起動方法は以下の通りです。
あるいは、IntelliJ IDEAなどのIDEで、「BootApplication」クラスを右クリックして起動しても大丈夫でしょう。
(デバッグ起動も可能です)
Build, Execution, Deployment > Build Tools > Gradle > Build and run using:
の箇所を「Gradle」としておきます。(デフォルトでこうなっています)
クライアントとサーバーのどちらを先に起動しても大丈夫ですが、今回はサンプルコードですので、ローカルホストのiOSシュミレーターかAndroidエミュレーターでしか動作しません。ご了承ください。
今回まででProtocol Bufferのスキーマ定義をクライアントとサーバーの双方で共有し、強調作業が行えるような運用のイメージが掴めました。
クライアントがWebフロントになっても、あるいはマイクロサービスなバックエンド間の通信も、このモデルを応用すればスキーマ定義を共有資産として管理し、双方で同じバージョンの型に対して開発することが可能なのではないかと考えています。
それでは!