gRPCとは
Google Remote Procedure Call(gRPC)は、HTTP/2を介してAPIを実装するための高性能なオープンソースフレームワークです。特にコードが異なるマシン上で実行される可能性がある場合に、開発者が分散アプリケーションをより容易に構築できるよう設計されています。
Google Remote Procedure Call(gRPC)は、HTTP/2を介してAPIを実装するための高性能なオープンソースフレームワークです。特にコードが異なるマシン上で実行される可能性がある場合に、開発者が分散アプリケーションを容易に構築できるよう設計されています。
gRPCは、Remote Procedure Call(RPC)を実装する技術として、Googleによって最初に開発されました。現在、gRPCはCloud Native Computing Foundationのインキュベーションプロジェクトであり、本番環境で利用され、活発なコントリビューターコミュニティによって支えられています。
gRPCが開発された理由
GoogleがgRPCを開発した理由を理解するために、まずはAPI設計の変遷を簡単に見てみましょう。
RPCは、APIを設計・構築する最も古い手法の1つです。RPCを使用すると、実際には別のマシン(通常はローカルネットワーク上)で稼働するサービスを呼び出す場合でも、ローカルコンピューター上で実行されるかのようにコードを記述できます。
実際には、これにより開発者はネットワークの詳細を考慮することなく、SendUserMessagesやaddEntryなどの直接的なアクションを使用できます。RPCメッセージは軽量で効率的ですが、基盤となるシステムと密結合しています。そのため、統合や変更が難しく、システムの詳細が漏洩する可能性も高くなります。
When the REST APIアーキテクチャの導入により、汎用的なHTTPメソッド(GET、POST、PUT、DELETE)を使用してデータやリソースに一貫した方法でアクセスできるようになり、こうした課題の一部が解決されました。RESTはデータアクセスを簡素化しますが、APIは必要以上のメタデータを返すことが少なくありません。また、REST APIではリクエストの送信先など、ネットワークに関する情報がより多く必要になるため、RPCほど軽量かつ効率的ではありません。
gRPCの利点
gRPCは新しいテクノロジーを採用することで、従来のRPC方式を刷新し、相互運用性と効率を高めています。現在では、マイクロサービスアーキテクチャ向けのAPIを開発する際に有力な選択肢となっています。
gRPCの主な利点は次のとおりです。
- パフォーマンス – gRPCは、HTTP/2をトランスポートプロトコルとして使用し、デフォルトでProtocol Buffersを使用するため、RESTとJSONによる通信よりもパフォーマンスが向上する可能性があります。
- ストリーミング – gRPCは、イベント駆動型アーキテクチャ向けのデータストリーミングをサポートします。これには、サーバーサイドストリーミング、クライアントサイドストリーミングのほか、クライアントリクエストの送信とサーバーレスポンスの返送を同時に行う双方向ストリーミングなどがあります。
- 相互運用性 – gRPCは、組み込みのコード生成機能により、C++、Java、Python、PHP、Go、Ruby、C#、Node.jsなど、幅広いプログラミング言語をサポートします。
- セキュリティ – gRPCは、セキュリティとレジリエンスの向上に役立つ、プラグイン可能な認証、トレーシング、負荷分散、ヘルスチェックを提供します。
- クラウドネイティブ – gRPCはコンテナベースのデプロイに適しており、KubernetesやDockerなどの最新のクラウドベース技術と互換性があります。
総じて、gRPCは、高度に分散されたマイクロサービスアーキテクチャにおけるサービス間通信に最適な、高性能で柔軟なフレームワークを提供します。
gRPCを理解する:基本概念
gRPCの利点とメリットは、主に次の2つのテクノロジーを採用していることによるものです。
- メッセージを構造化するためのProtocol Buffers
- トランスポート層としてのHTTP/2
メッセージを構造化するためのProtocol Buffers
gRPCでは、XMLやJSONの代わりにProtocol Buffers(Protobufs)を使用して、サービスとメッセージを定義します。これは、サービス間で送受信される構造化メッセージをシリアル化するための、プログラミング言語に依存しない仕組みです。
REST API向けのOpenAPI Specificationと同様に、gRPCのAPIコントラクトは.protoテキストファイルで実装され、開発者はこのファイルでデータ構造を定義します。その後、protocコンパイラが.protoテキストファイルをサポート対象の任意の言語に自動的にコンパイルします。実行時には、メッセージが圧縮され、バイナリ形式で送信されます。
これにより、主に2つのメリットが得られます。
- gRPCではデータがバイナリ形式で表現され、メッセージサイズが小さくなるため、CPU負荷が軽減されます。
- スキーマが明確に定義されているため、クライアントとサーバー間でメッセージを円滑に交換でき、エラーを削減できます。
トランスポート層としてのHTTP/2
従来、REST APIではトランスポート層としてHTTP/1.1が使用されていました。REST APIもHTTP/2経由で提供できますが、gRPCはHTTP/2のみを使用することで、いくつかの重要な利点をもたらします。その1つが、バイナリ形式で通信できることです。また、HTTP/2では、リクエストを1件ずつ処理するのではなく、複数のリクエストを並列処理できます。さらに双方向通信にも対応しているため、単一の接続でリクエストとレスポンスを同時に送信できます。
全体として、これによりパフォーマンスが向上し、ネットワーク使用量が削減されます。これは、負荷の高いマイクロサービスアーキテクチャで特に有用です。ただし、いくつかの制約もあります。一般に、最新のWebブラウザーはHTTP/2をサポートしていないため、アプリケーションを配信するには、NGINXなどのリバースプロキシを使用する必要がある場合があります。
gRPCとRESTの比較
現在、RESTは最も広く採用されているAPI設計スタイルであり、gRPCと比較する際の有用な基準となります。RESTとgRPCはどちらも、Webアプリケーションやマイクロサービス向けのAPIを構築するうえで有効なアプローチであり、必ずしも一方が他方より優れているわけではありません。用途に最適な手法を選ぶには、両者の主な違いを理解することが重要です。
gRPCとRESTの主な違いには、次のようなカテゴリがあります。
- プロトコル
- データ形式
- ストリーミング
- API設計
- パフォーマンス
- エラー処理
- 言語サポート
プロトコル
REST APIではHTTP/2を利用できますが、RESTfulサービスでは従来、テキストベースのHTTP/1.1をトランスポート層として使用しています。gRPCは、より効率的なバイナリプロトコルであるHTTP/2のみを使用し、ヘッダー圧縮や単一のTCP接続上での多重化などの機能を実現します。
データ形式
REST APIでは通常、データの送受信に使用するデータ形式としてJSONが採用されます。JSONはテキストベースで読み書きしやすく、幅広くサポートされています。gRPC APIではProtobufsが使用されます。Protobufsはバイナリ形式であるため、ペイロードを小さくし、やり取りを高速化できます。ただし、Protobufsをそのまま読み取ることは容易ではありません。
ストリーミング
REST APIはリクエスト/レスポンスモデルをサポートしていますが、ストリーミングのサポートは限定的です。一方、gRPC APIはHTTP/2経由で提供され、Unary(リクエスト/レスポンス)、サーバーストリーミング、クライアントストリーミング、双方向ストリーミングなど、複数の通信パターンをサポートしています。
API設計
RESTは、GET、POST、PUT、DELETEなどの標準HTTPメソッドをサポートする、リソース中心のモデルです。各リクエストには、その処理に必要なすべての情報を含める必要があります。また、APIコントラクトは通常、OpenAPI Specificationを使用して記述し、クライアントとサーバーのコーディングは別の工程として扱います。一方、gRPCはサービス中心のモデルであり、メッセージとサービスを.protoファイルで定義します。このファイルを使用して、APIクライアントとサーバーの両方のコードを生成できます。
パフォーマンス
RESTは、HTTP/1.1でテキストベースのデータを送信するため、処理が遅くなる場合があります。リクエストごとにTCPハンドシェイクが必要となり、多少の遅延が生じる可能性があります。gRPCはHTTP/2上で複数のストリームをサポートしているため、複数のクライアントが新しいTCP接続を確立することなく、複数のリクエストを同時に送信できます。また、ヘッダー圧縮などのHTTP/2機能も活用します。
エラー処理
RESTでは、エラー処理に標準のHTTPステータスコードを使用します。一方、gRPCでは、エラーステータスコードをより詳細に定義し、一貫性を確保できます。デフォルトのgRPCモデルはかなり限定的ですが、一般的には、より充実したGoogleが開発したエラーモデルを使用して拡張されます。
対応言語
RESTはほぼすべての言語で広くサポートされていますが、コード生成機能は組み込まれていません。実装はすべて開発者に委ねられます。一方、gRPCではprotocコンパイラにより、複数のプログラミング言語向けにネイティブコードを生成できます。
RESTの代わりにgRPCを使用すべきか?
要約すると、gRPCとRESTのどちらを選ぶかは、実現したいことによって異なります。gRPCは、分散アプリケーション内のサービス間で効率的かつ高性能な通信を実現する手段です。ただし、Webブラウザーなどのクライアントでは直接読み取れないため、フロントエンドクライアントと通信するには、APIゲートウェイまたはNGINXのようなリバースプロキシが必要です。イベント駆動型マイクロサービスアーキテクチャを構成する内部APIに最適な選択肢です。
一方、RESTは広く採用されており、ほぼすべての言語でサポートされています。JSONまたはXMLを使用してデータを交換するため、人間にも機械にも読み取ることができます。また、導入時の学習負担がはるかに少なく、多くのWebブラウザでサポートされているため、一般公開するAPIに最適です。
gRPCマイクロサービスアーキテクチャ
gRPCは、マイクロサービスアーキテクチャにおける通信に最適な選択肢の1つです。その理由は、パフォーマンスの高さに加え、幅広い言語を柔軟にサポートしていることにあります。開発者は、希望する言語で動作するgRPCクライアントとサーバーを容易に構築、生成できます。gRPCではAPIコントラクトをバイナリ形式で記述するため、マイクロサービスは実装に使用された言語にかかわらず相互に通信できます。
最も一般的なgRPCベースのマイクロサービスアーキテクチャの1つは、マイクロサービスの前段にAPIゲートウェイを配置し、すべての内部通信をgRPCで処理する構成です。APIゲートウェイはHTTP/1.1経由の受信リクエストを処理し、HTTP/2経由のgRPCリクエストとしてマイクロサービスにプロキシします。
gRPCのセキュリティ上の懸念事項
gRPCの導入が進む中、開発者とセキュリティ運用チームは、効果的なセキュリティソリューションが導入されていることを確認する必要があります。gRPCメッセージはバイナリ形式であるため、ASCIIベースの通信を前提とするデバイスやツールでは問題が生じる可能性があります。
gRPC APIも、多くの一般的なAPIセキュリティ脅威に対して脆弱です。アクセス制御、暗号化、ランタイム保護などの標準的なAPIセキュリティ対策は、gRPCベースのアーキテクチャでも同様に重要です。
gRPCセキュリティに関する推奨事項
gRPCアプリケーションとAPIのセキュリティには、包括的なアプローチが必要です。gRPCを保護するためのベストプラクティスには、次のようなものがあります。
- スキーマ検証 – gRPCメッセージ内の各フィールドが正しい型であり、想定される内容であることを確認して、悪意のあるエクスプロイトをブロックします。
- データマスキング – クレジットカード番号や社会保障番号などの機密データがシステム外に流出しないよう、マスキングまたはブロックします。
- レート制限 – リクエストのサイズと数に厳格な上限を設定し、リソース枯渇型のDoS攻撃を防止します。
- アクセス制御 – クライアントにサービスへのアクセスを許可する前に、認証と認可を適用します。
- 暗号化 – Transport Layer Security(TLS)を使用して、転送中のメッセージを保護します。
最終的には、使用しているAPIゲートウェイ、Webアプリケーションファイアウォール(WAF)、その他のAPI管理およびセキュリティツールが、本番環境のgRPCアプリケーションとAPIを保護するために十分な機能を備えていることを確認する必要があります。これらのツールは、各サービスの.protoファイルをインポートし、それを使用してgRPCアプリケーションとAPIにセキュリティ保護を適用できる必要があります。
まとめ
gRPCは、開発者やNetflix、Lyftのような大企業がマイクロサービスアーキテクチャで利用する選択肢として人気が高まり、大きな注目を集めています。ただし、gRPCはREST APIに代わるものではなく、APIを構築する方法として本質的に優れているわけでもありません。主に社内のマイクロサービス環境向けにAPIを構築し、効率的なリアルタイム通信を必要とする場合に検討できる選択肢の1つです。
今後、gRPCは、パフォーマンス上の利点と開発のしやすさから、クラウドネイティブアプリケーションでさらに普及していくと考えられます。一方、APIを一般公開する必要がある開発者は、引き続きアプリケーションでRESTを使用するでしょう。また、RESTは後方互換性を備え、既存のAPIインフラストラクチャや運用に深く統合されているため、クラウドネイティブ環境でも引き続き利用されると考えられます。

