この記事はtraP Advent Calendar 2021 42日目の記事です。
こんにちは、20Bのxxarupakaxxです。
今回はgRPCについて解説していきます。
※本記事ではgRPCのサンプルコードはございません。ただただgRPCについて話していきます。
自分が所属しているプロジェクトのミーティングでgRPCについて話題が上がり実際にgRPCで開発を進める方針になったので自分が調べた限りの知見をまとめて共有しようかなと思います。
gRPCってなんぞや
gRPCって聞かれてもなんも思いつかないですよね.. gがついているから、Googleがなんか作ったんじゃないのって思うそこのあなた!そうです、Googleが開発したものなんです!!ですが、g + RPC..
RPCってなんだろうと思う方が多いかと思います。なのでまずRPCについて軽く説明していきます。
RPCってなに
RPCとは、Remote Procedure Callの略で逐語的に遠隔手続き呼び出しと訳されます。すなわち、別の場所にあるプログラムを呼び出そうっていう意味になります。もっと詳しく説明すると、違うアプリケーションロジックをあたかも自分のアプリケーションの処理と同じように扱えることができるというものです。
gRPC以外にもJSON-RPC,XML-RPCなどがあります。
gRPCについて
では本題のgRPCについて触れていきたいと思います。
gRPCの利点は大きく三つの点が挙げられます。
- HTTP/2による高速な通信
- バイナリにシリアライズされて送られてくる
- 小さな容量で転送できる
- 一つのコネクションで複数のres/reqが可能
- Protocol buffers
- 自分でAPIインターフェイスを実装したりシリアライズされたデータのエンコード/でコード処理を書く必要がない
- 柔軟なストリーミング形式
- 単方向/双方向ストリーミングRPCに対応している
これは、gRPCの性質の利点ですが開発を進めるうえでgRPCを導入することで得られる素晴らしい恩恵はスキーマファーストであることです。
protoファイルを先に定義するのでAPIの仕様が初期の段階に整っており、常に仕様が確認できる状態にあるということ、これが素晴らしいのです!
こういう点から僕はgRPCを推していきたいですね(gRPC自体も性能として素晴らしいものばかりです)
gRPCの通信の種類
gRPCは様々な通信方式を可能にします。そしてそれらは簡単に実装ができます。
Unary RPC
1つのリクエストに対して一つのレスポンスを返す一般的な通信です。REST APIと動きは似ています。
Server streaming RPC
クライアントから送られてきた一つのリクエストに対して、複数回に分けてレスポンスを返す通信方式です。最後のレスポンスを返した後も任意にサーバーの情報を変更に応じてクライアントにその情報を送ることができます。
Client streaming RPC
クライアントからリクエストを分割して送ってサーバーはすべてのリクエストを受け取ってからレスポンスを返します。大きなデータをPOSTしたいときに便利です。
Bidirectional streaming RPC
クライアントからリクエストが送られてきたときにサーバーとクライアントは一つのコネクションを確立しお互いに任意のタイミングでリクエストとレスポンスを送りあうことが可能になります。
WebSocketが脳裏に浮かぶ方もいるかと思います。WebSocketはREST APIで主に用いられますがWebSocket用のサーバーを別途で用意する必要があり少し手間が存在します。また、gRPC(HTTP/2)は無駄な情報が少ないのでWebSocketと比べて高速です。
以上がgRPCの説明でこれが理解できれば、gRPCはどのようなものかがわかるかと思います。
次にgRPCを学習するにつれて出会う用語について説明したいと思います。
gRPC-Web
gRPC通信をWebで使うことができるというものです。つまりgRPCをブラウザで動けるようにブラウザの制限にあわせたプロトコルを定義しているものです。
HTTPサーバーが仲介者として機能することなく、WebアプリがgRPCバックエンドサービスと直接通信できるようになるものですね。またクライアントもバックエンドもgRPCでの実装なので完全なエンドツーエンドのgRPCサービスアーキテクチャを作成できることが利点です。protoファイルに記述したらあとはお互い実装あるのみで開発も進められやすいです。
ですが、gRPC-Webでブラウザを使うのにはプロキシを挟む必要があります。(envoyとかnginxとか)
grpc-webにはmode = grpcwebtext
, mode = grpcweb
の二種類のモードがありコンテンツタイプは、それぞれapplication/grpc-web-text
,application/grpc-web+proto
であります。
しかしgrpcwebtext
はUnaryとServer streamingがサポートされているがgrpcweb
は現在のところ、Unaryのみとなっています。
gRPC-Webの詳細はこちらで確認できます。
gRPC-WebとREST API
gRPCのほうがREST APIと比べて高速です。ですが、クライアントがRESTfulな開発を進めていてからのgRPCへ移行は厳しいものがあります。ほぼすべてをgRPCベースに書き換える必要があるのでgRPCで得られる恩恵よりもコストが高く感じられます。
gRPC-Gateway
gRPC-GatewayはgRPCで書かれたAPIをJSONまたはgRPCで提供できるプロキシです。
protoファイルに書かれたサービスの定義をgRPC-Gatewayは理解し、それをREST APIのように変換してくれます。envoy等のプロキシを挟む必要がなく(あってもよい)gRPC-GatewayだけでRESTfulなAPIを受け取れます。また、protoファイルからswagger.jsonを自動出力してくれる機能も備わっており、ドキュメント生成に関しては申し分ないです!この自動生成を使えばすぐさまAPIの仕様を管理&&修正できるのでもうやばいですね
ですが、gRPC-Webと比べて、JSONの解析に時間がかかりgRPC-Webと比べたらパフォーマンスは落ちます。
gRPC-Gatewayの詳細はこちらで確認できます。
envoyでもいいのでは?
先ほど説明した通り、gRPC-GatewayとenvoyはどちらもJsonをgRPCに変換してくれる機能を持ち合わせています。
ですがenvoyは高機能なプロキシソフトウェアであって負荷分散や圧縮やアクセスログの出力もnginx等と同じように使えます。また、gRPC-GatewayはGo言語でのみの対応であるが、envoyは他言語にも対応しています。
使い道はどちらでもいいですが、JSONを変換してくれるだけでいい+Golang実装だったら、gRPC-Gatewayでいいのかなと思います。
最後に
gRPCのgってGoogleのgじゃないんですよね。gRPCのg
の意味合いはバージョンごとに異なります。
1.0のときはg
はgRPC
を表し,その次の1.1のときはgood
を表します。現在最新のバージョンである1.44ではgreat
を表すそうです。詳細はこちらで確認できます。
また余談ですがサムネイルの子犬キャラクターかわいいですよね!!実は、gRPCのマスコットで犬種がGolden Retrieverで名前はPanCakesです。よくみるとgRPCという文字が隠れていますね!!本当にかわいい!!!!!!!!
機会があれば、gRPCを実際に用いた記事を書きたいと思います!!
明日のAdCは@mazreanさんです。楽しみですね~~!!