1. HOME
  2. ブログ
  3. IT技術
  4. 【Flutter】gRPCを使ってAPI通信を実装する【後編】

【Flutter】gRPCを使ってAPI通信を実装する【後編】

はじめに

近々gRPCを使ってAPI通信するFlutterアプリを開発する機会があるので、そこに向けた事前準備&備忘録として対応内容を記録していきます。

本記事では前編記事に引き続き、gPRCの下記4つの通信方式すべてのパターンで実装した内容をまとめます。

  • Unary RPC (単一リクエスト, 単一レスポンス)
  • Server streaming RPC (単一リクエスト, 複数レスポンス)
  • Client streaming RPC (複数リクエスト, 単一レスポンス)
  • Bidirectional streaming RPC (複数リクエスト, 複数レスポンス)

環境構築については前編記事にまとめているのでそちらを御覧ください。
またgRPCとは?という部分の説明は省きますので、詳細を知りたい方は公式ドキュメントを御覧ください。

前編はこちら

開発環境

開発環境は以下の通りです。

Dart2.18.2
Flutter3.3.4
protoc3.21.7

Unary RPC (単一リクエスト, 単一レスポンス)

まずは、Unary RPCでの通信を実装してみます。

Unary RPCは単一リクエスト、単一レスポンスなので、下記のようなユースケースで利用できそうです。

  • リクエストとレスポンスが時間経過や状態変化で変わることがない、または変更を通知する必要がない

前編記事で実装したHello, worldアプリもUnary RPCでしたが、おさらいということで今回は少し内容を変えて「10進数の数字を2進数へ変換する計算が正しいかどうかを判定する」機能を作成してみます。

サーバー側

サーバー側の準備を行います。

リクエストとして10進数の数字と2進数の数字文字列を受け取り、レスポンスとして正誤結果と正しい2進数の数字文字列を返却するようにします。

まずは、 server/protos に今回作るサービス用のprotoファイルを作成します。

次にgRPCのDart用コードを出力します。
前編同様に共通パッケージの grpc_gen の lib/src 内に出力します。
前編ではsrc直下に出力しましたが、今回は機能ごとにディレクトリを切って出力していきます。

利用する側が自動生成されたファイル郡を意識せずに扱えるようにするために、各ファイルのexportも設定します。

grpc_gen/lib/src/decimal_to_binary/decimal_to_binary.dart

grpc_gen/lib/grpc_gen.dart

最後に ConverterServiceBase を継承した ConverterService クラスを lib/converter_serevice.dart として作成し、 bin/server.dart内でサーバーアプリを起動するmain処理のサービス一覧に追加します。

server/lib/converter_service.dart

server/bin/server.dart

これでサーバー側の実装および準備は完了です。

アプリ側

サーバー側の準備が完了したので、次はアプリ側の実装を行っていきます。

前編記事にてHello, world機能のあるアプリを作成したので、依存パッケージやサーバーにアクセスするためのチャンネルを生成する Provider などはそのまま流用し、同じアプリ内に機能追加する形で新しい画面を追加していきます。

まずは、入力する10進数と2進数を保持する StateProvider を実装します。

ついでに数字が有効な場合のみ「答え合わせ」ボタンを活性にするために、変換可能かどうかを判定する Provider も作成しておきます。

次に、入力された10進数と2進数をもとに答え合わせの結果を保持・更新する StateNotiferProvider を実装します。

ボタンが押されたときに check() 、数字が変更されたときには reset() が呼ばれる想定です。

最後に、表示する Widget を作成します。

以上でアプリ側の実装は完了です。

動作確認

それでは動作確認してみます。

10進数と対応する2進数を入力して「答え合わせ」ボタンをタップすると…

無事答え合わせができました!

Server streaming RPC (単一リクエスト, 複数レスポンス)

次は、Server streaming RPCでの通信を実装していきます。

Server streaming RPCは単一リクエスト、複数レスポンスなので、下記のようなユースケースで利用できそうです。

  • リクエストに対するレスポンスが時間経過や状態変化で変化する、かつ変化を監視する必要がある

上記を満たす機能として、「秒間隔をリクエストとして送信し、送信された間隔ごとに時刻を返す」機能を作成してみます。

サーバー側

サーバー側の実装をしていきます。

リクエストとして秒間隔を受け取り、レスポンスとして秒間隔ごとにUNIX時間を返却するものを定義します。

まずは、 server/protos に今回作るサービス用のprotoファイルを作成します。

レスポンスの前にstreamを付与するのがポイントです。
また、UNIX時間は int32 に収まらないので int64 で定義します。

次にgRPCのDart用コードを出力します。

利用する側が自動生成されたファイル郡を意識せずに扱えるようにするために、各ファイルのexportも設定します。

grpc_gen/lib/src/time_notification/time_notification.dart

grpc_gen/lib/grpc_gen.dart

最後に TimeNotifierServiceBase を継承した TimeNotifierService クラスを lib/time_notifier_service.dart に作成し、 bin/server.dart 内でサーバーアプリを起動するmain処理のサービス一覧に追加します。

server/lib/converter_service.dart

server/bin/server.dart

これでサーバー側の実装および準備は完了です。

アプリ側

サーバー側の準備が完了したので、次はアプリ側の実装を行っていきます。

まずは、入力した間隔を保持する Provider を実装します。

次にサーバーから取得した時間をStreamで受け取る Provider を実装します。

最後に表示する Widget を作成します。

以上でアプリ側の実装は完了です。

動作確認

それでは動作確認をしてみます。

取得したい時間の間隔を入力して「時間取得開始」ボタンをタップすると…

無事指定した間隔ごとに時間が取得できていることが確認できました!

Client streaming RPC (複数リクエスト, 単一レスポンス)

続いては、Client streaming RPCでの通信を実装していきます。

Client streaming RPCは複数リクエスト、単一レスポンスなので、下記のようなユースケースで利用できそうです。

  • レスポンスに対するリクエストが時間経過や状態変化で変化する、かつ変化を監視する必要がある

上記を満たす機能として、「aから始まる英単語を5秒以内に何個挙げられるかを計測する」機能を作成してみます。

サーバー側

サーバー側の実装をしていきます。

リクエストとして単語を受け取り、レスポンスとして送られてきた単語の数を返却するものを定義します。

まずは、 server/protos に今回作るサービス用のprotoファイルを作成します。

今回はリクエストの前にstreamを付与します。

次にgRPCのDart用コードを出力します。

利用する側が自動生成されたファイル郡を意識せずに扱えるようにするために、各ファイルのexportも設定します。

grpc_gen/lib/src/word_count/word_count.dart

grpc_gen/lib/grpc_gen.dart

最後に WordCounterServiceBase  を継承した WordCounterService クラスを lib/word_counter_service.dart に作成し、 bin/server.dart 内でサーバーアプリを起動するmain処理のサービス一覧に追加します。

server/lib/word_counter_service.dart

server/bin/server.dart

これでサーバー側の実装および準備は完了です。

アプリ側

サーバー側の準備が完了したので、次はアプリ側の実装を行っていきます。

まずは、入力した単語をStreamに追加してくためのControllerを保持する Provider を実装します。

次に、入力した単語の数を取得する Provider を実装します。

5秒後にstreamに対してclose処理を呼び出し、レスポンスが受け取れるようにしています。

最後に表示する Widget を作成します。

以上でアプリ側の実装は完了です。

動作確認

それでは動作確認をしてみます。

「開始!」ボタンをタップして単語を入力していくと…

無事5秒以内に入力した単語数がレスポンスとして返却されるような機能ができました!

Bidirectional streaming RPC (複数リクエスト, 複数レスポンス)

最後は、Bidirectional streaming RPCでの通信を実装していきます。

Client streaming RPCは複数リクエスト、複数レスポンスなので、下記のようなユースケースで利用できそうです。

  • リクエストおよびレスポンスが時間経過や状態変化で変化する、かつ変化を監視する必要がある

上記を満たす機能として、複数端末を使って匿名チャットができる機能を作成してみます。

サーバー側

サーバー側の実装をしていきます。

リクエストとしてメッセージを受け取り、レスポンスとしてこれまでのメッセージ一覧(時刻付き)を返却するものを定義します。

まずは、 server/protos に今回作るサービス用のprotoファイルを作成します。

今回はリクエストとレスポンスの前にそれぞれstreamを付与します。

次にgRPCのDart用コードを出力します。

利用する側が自動生成されたファイル郡を意識せずに扱えるようにするために、各ファイルのexportも設定します。

grpc_gen/lib/src/time_notification/time_notification.dart

grpc_gen/lib/grpc_gen.dart

最後に ChatConnecterServiceBase  を継承した ChatConnecterService クラスを lib/chat_connecter_service.dart に作成し、 bin/server.dart 内でサーバーアプリを起動するmain処理のサービス一覧に追加します。

server/lib/chat_connecter_service.dart

server/bin/server.dart

これでサーバー側の実装および準備は完了です。

アプリ側

サーバー側の準備が完了したので、次はアプリ側の実装を行っていきます。

まずは、アプリ側からメッセージを流すためのStreamを管理するControllerを保持する Provider を実装します。

次に取得したメッセージ一覧のStreamを保持する Provider を実装します。

最後に表示する Widget を作成します。

以上でアプリ側の実装は完了です。

動作確認

それでは動作確認をしてみます。

それぞれの端末でメッセージを送信してみると…

それぞれの端末でメッセージの送受信が確認できました!

まとめ

本記事ではgRPCの下記4つの通信方式を使ってFlutterアプリ内でAPI通信を行う実装をまとめました。

  • Unary RPC (単一リクエスト, 単一レスポンス)
  • Server streaming RPC (単一リクエスト, 複数レスポンス)
  • Client streaming RPC (複数リクエスト, 単一レスポンス)
  • Bidirectional streaming RPC (複数リクエスト, 複数レスポンス)

各機能がシンプルなものだったのもありますが、Streamを使った機能がサクッと実装できました。

gRPCをFlutterアプリで導入しようと考えている方の参考になれば幸いです。

書いた人はこんな人

広告メディア事業部
広告メディア事業部
「好きを仕事にするエンジニア集団」の(株)ライトコードです!

ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。

システム開発依頼・お見積もり大歓迎!

また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。

以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア