会社でgRPCを導入する方針があり、gRPCについて色々調べてみたのでまとめてみます。

私が現在分からないところを、私が分かる言葉の組み合わせで説明できるまで噛み砕くように調べたので、調べる粒度とかはバラバラです。私がgRPCを理解できること、それが本記事の主目的である。

gRPCってなんやねん

  • Google で開発された多言語間のRemote Procedure Call (RPC) を実現するプロトコル
  • IDL としては Protocol Buffers が使われている。
  • 通信には HTTP/2 の枠組みが利用されている。

軽く調べてみると、上記の説明がサラッと書いてあるので、ここから噛み砕いていきます。

じゃあRPCってなんなのよ

  • 上記の通りRemote Procedure Callの略で、外部のプログラムが提供するプロシージャを呼び出す仕組み。
  • 各言語の普通の関数(stub 関数)を呼び出すとライブラリがネットワーク通信して外部で動作しているサーバーにリクエストを投げ、結果を受け取って関数の戻り値として返す。
  • RPC の利用者視点ではネットワークや他の言語の知識を必要とすることなく、ただの関数として利用できる。
  • 異なる言語間で RPC として呼び出せる関数を定義する場合、特定の言語に依らない独立の定義方法が必要になる。

    • RPCの関数やその引数を定義する言語を Interface Description Language (IDL) という。

gRPCのサーバーとクライアントの関係が 以下のページに図で説明されております。

grpc_intro

Rubyクライアントからでも、Android-Javaクライアントからでも、stubとしてC++で書かれているgRPCサーバーの関数を使えるというイメージが、見て分かるかと思います。

じゃあIDLってなんなのよ

  • 上記の通り、RPCの関数やその引数を定義する言語のこと
  • IDL にはコンパイラが付属し、サポートしている言語用に関数呼び出しのためのコードを自動生成する。

    • 例えばクライアントが Python でサーバーが Go の場合、Python の文字列リストをネットワークで送れるようバイト列にserializeし、Go では受け取ったバイト列を deserialize して Goの文字列スライスするような serialize / deserialize コードをIDL コンパイラが生成してくれる。

じゃあProtocol buffersってなんなのよ

  • スキーマ言語の一種
  • 簡素で可読で、プログラミング言語から独立で、任意のデータを表現できるわけではないが十分に適用可能範囲が広い。
  • 仕様が小さいので、実装間の意図せぬ非互換性で苦しめられることが少ない。
  • Protocol Buffersのversion 3からは、Jsonとの相互変換の規則が仕様として定められてる。

え、HTTP/2ってなんだっけ

  • 従来使われてきたHTTP/1.1では、ウェブサーバーに対して原則1つずつしかリクエストを送ることができなかった。一方、新しく登場したHTTP/2では、複数のリクエストを同時に処理することができる。

中間まとめ

上記より、gRPCってなんやねんの説明を噛み砕いてみます。

  • Google で開発された多言語間のRemote Procedure Call(外部のプログラムが提供するプロシージャを呼び出す仕組み)を実現するプロトコル
  • IDL (RPCの関数やその引数を定義する言語) としては Protocol Buffers (スキーマ言語の一種) が使われている。

    • 普通のRPCであれば、Java IDLとかでも書けるっぽい。
  • 通信には HTTP/2 (HTTP/1.1から複数リクエストを同時に処理できるようになったプロトコル)の枠組みが利用されている。

よしよし、だいぶ分かってきた。 ここからちょっと気になったことを調べます。

APIとの関係は?

「じゃあRPCってなんなのよ」にて、RPCは外部のプログラムが提供するプロシージャを呼び出す仕組みだという説明がありましたが、これは要するにAPIよね??ってのが気になりました。 ちょっと調べてみると、そのとおりだったみたいで、SOAP,REST,GraphQLなどと肩を並べて比較されるAPIアーキテクチャの一種みたいです。

RPCとRESTの比較

以下の記事にて、分かりやすく説明されておりました。

RPC形式のメリット

  • 複数言語に渡るプログラム間で条件分岐する場合でも直接メソッドでの操作が可能
  • 仕様によってはGETかPOSTかすら気にせず、すべてPOSTで対応可能なシンプルさ
  • メソッドが直接エンドポイントに作用するので機能追加がしやすい
  • ペイロードが軽量になるので最善なパフォーマンスがで出やすい

REST形式のメリット

  • フロントエンドで使われる技術をそのまま使える(JSが扱いやすいJSONベース)ので汎用性が高い
  • HTTPプロトコルによって一貫性かつ互換性のある操作を行える(登録はPOST、取得はGET、削除はDELETEなど)
  • URLを検索することで、URLの機能とそのレスポンス情報を解読しやすい&エンドポイントを見ればどういうデータが行き交ったのかが理解しやすい
  • サーバー側とは受け取るリソースのみの認識共有で済むので、フロントとバックがそれぞれの相互依存気にせず開発に集中できる

URLの違い

RPCとRESTはURLにも違いが出るようで、それに関しては以下の記事に画像が乗ってました。

見た感じ、以下の記事の日本語訳っぽいですね

url_differ

「~をする」ということをURLに明記する、いわば動詞を記載するRPCと、「~がほしい」といった、明示的にユニークキーなどを指定する、いわば名詞を記載するRESTというところで違いがあるそう。



その他、SOAP,REST,RCP,GraphQLの比較表などもあるので、上記の記事はAPI設計の際にはかなり参考になりそうですね。

とりあえずgRPCとかRPCの概要は理解できたので、めでたしめでたし。

参考資料

いろいろ参考にさせていただきました。 特に、一番上に記載した、サイボウズの社内研修向け資料は、サンプルコードなどもあって、大変参考になりました。