grpcurl について
grpcurl は HTTP の curl に似た方式で gRPC サービスと対話するコマンドラインツールです。利用可能なサービスの一覧表示、メソッドシグネチャの検査、gRPC エンドポイントへのリクエスト送信などが可能で、クライアントコード開発なしに gRPC サーバーと通信できます。
主な機能
- 01gRPC サーバー上の利用可能なサービスとメソッドを一覧表示
- 02メソッドシグネチャとパラメータ定義を検査
- 03gRPC エンドポイントにリクエストを送信して応答を受け取り
活用シーン
- 01gRPC API の機能を対話的にデバッグとテスト
- 02開発中に gRPC サービス定義を探索
- 03gRPC サーバーの可用性とメソッドシグネチャを検証
インストール
OS またはパッケージマネージャーを選び、コマンドをターミナルで実行します。
インストール後にgrpcurl --versionを実行して確認します。
コマンド例
よく使うコマンドを使う順に並べています。
詳細
gRPCurl
grpcurlは、gRPC サーバーとやり取りするためのコマンドラインツールです。
基本的には、gRPC サーバー向けのcurlです。
このツールの主な目的は、コマンドラインから gRPC サーバー上の RPC メソッドを呼び出すことです。gRPC サーバーでは、通信時にバイナリーエンコーディング(プロトコルバッファー、略して「protobuf」)が使用されます。そのため、通常のcurl(もちろん、HTTP/2 をサポートしていない古いバージョンのcurlも使えません)では基本的にやり取りできません。このプログラムは JSON エンコーディングのメッセージを受け付けるため、人間にもスクリプトにも扱いやすくなっています。
このツールでは、サーバーリフレクションをサポートするサーバーへのクエリ、proto ソースファイルの読み込み、またはコンパイル済みの「protoset」ファイル(エンコードされたファイル記述子 protoを含むファイル)の読み込みによって、gRPC サービスのスキーマを参照することもできます。実際、このツールが JSON リクエストデータをバイナリーエンコードされた protobuf に変換する際にも、まさに同じスキーマを使用します。そのため、やり取りするサーバーがリフレクションをサポートしていない場合は、サービスを定義する proto ソースファイル、またはgrpcurlが使用できる protoset ファイルが必要です。
このリポジトリでは、ライブラリパッケージgithub.com/fullstorydev/grpcurlも提供しています。このパッケージには、gRPC エンドポイントを動的に呼び出すほかのコマンドラインツールの構築を簡単にする関数が含まれています。このコードは、protoreflectライブラリのさまざまなパッケージの使い方を示す優れた例であり、それらの機能も紹介しています。
grpcurlについてのGopherCon 2018の講演もご覧ください。
機能
grpcurlは、ストリーミングメソッドを含む、あらゆる種類の RPC メソッドをサポートしています。対話型ターミナルからgrpcurlを実行し、標準入力をリクエスト本文として使えば、双方向ストリーミングメソッドも対話形式で実行できます。
grpcurlは、セキュアな/TLS サーバーとプレーンテキストサーバー(つまり、TLS なし)の両方をサポートし、TLS の設定に関する多数のオプションを備えています。また、クライアント証明書の提示がクライアントに求められる相互 TLS もサポートしています。
前述のとおり、サーバーがリフレクションサービスをサポートしていれば、grpcurlは問題なく動作します。サポートしていない場合は、.protoソースファイル、またはgrpcurlに渡す protoset ファイル(protocで生成したコンパイル済み記述子を含むファイル)を指定できます。
インストール
バイナリー
リリースページからバイナリーをダウンロードしてください。
Homebrew(macOS)
macOS では、grpcurlを Homebrew からインストールできます。
brew install grpcurl
Docker
Docker をサポートするプラットフォームでは、grpcurlを実行できるイメージをダウンロードできます。
# Download image
docker pull ghcr.io/fullstorydev/grpcurl:latest
# Run the tool
docker run ghcr.io/fullstorydev/grpcurl api.grpc.me:443 list
Docker を使用する際には、いくつか注意点があります。
- ホストのループバックネットワークで待ち受けているサーバーとやり取りする必要がある場合は、ホスト名として
localhostではなくhost.docker.internalを指定する(Mac または Windows の場合)か、コンテナーでホストネットワークを使用する必要があります(-network="host"、Linux のみ)。 - proto ソースファイルまたは記述子セットを指定する必要がある場合は、それらのファイルを含むフォルダーをボリュームとしてマウントし(
-v $(pwd):/protos)、それに合わせてインポートパスをコンテナー内のパスに変更する必要があります。 -d @オプションを使って標準入力からリクエストメッセージを渡す場合は、Docker コマンドに-iフラグを指定する必要があります。
その他のパッケージ
grpcurl をインストールする方法はほかにも数多くあります。サードパーティが
grpcurl 用のレシピやパッケージを作成しているためです。Windows や多数の Linux
ディストリビューションを含む、さまざまな環境に grpcurl をインストールする方法があります。
grpcurl のその他のパッケージについての詳細と一覧は、repology.org で確認できます:
https://repology.org/project/grpcurl/information
Snap
snap パッケージを使って grpcurl をインストールできます:
snap install grpcurl
ソースから
すでに Go SDK をインストールしている場合は、go
ツールを使って grpcurl をインストールできます:
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
このコマンドは、環境変数 $GOPATH が指す場所の bin サブフォルダーにコマンドをインストールします。(環境変数
GOPATH が設定されていない場合、デフォルトのインストール先は $HOME/go/bin です。)このディレクトリがすでに
$PATH に含まれていれば、そのまま使用できます。
このリポジトリを $GOPATH に含まれない場所にすでに取得していて、ソースからビルドしたい場合は、リポジトリに
cd してから make install を実行します。
コンパイルエラーが発生し、1.13 より古いバージョンの Go SDK を使用している場合は、
grpcurl の依存関係が古くなっている可能性があります。make updatedeps を実行すると、依存関係を更新できます。また、Go 1.11 または 1.12 を使用している場合は、
上記のコマンドの前に GO111MODULE=on を付けると、適切なバージョンの依存関係を使ってビルドできます(GOPATH にすでにある依存関係ではなく)。
使用方法
このツールの使用方法ドキュメントでは、さまざまなオプションについて説明しています:
grpcurl -help
以下のセクションでは、grpcurl の使用方法を示すさまざまな例を紹介します。
RPC の呼び出し
信頼できるサーバー(例:自己署名鍵やカスタム CA を使用しない TLS)上の RPC を呼び出す場合、クライアント証明書が不要で、サーバーリフレクションをサポートしているなら、grpcurl を使うのが最も簡単です。この最小限の呼び出しでは、空のリクエスト本文を送信します:
grpcurl grpc.server.com:443 my.custom.server.Service/Method
# no TLS
grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method
空でないリクエストを送信するには、-d 引数を使用します。すべての引数は、サーバーアドレスとメソッド名より
前に 指定する必要があります:
grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \
grpc.server.com:443 my.custom.server.Service/Method
例から分かるように、指定する本文は JSON 形式である必要があります。本文は解析された後、protobuf のバイナリ形式でサーバーに送信されます。
jq でリクエスト本文を作成する場合など、コマンドパイプラインで grpcurl を使うには、-d @ を使用します。これにより、grpcurl は stdin から実際の
リクエスト本文を読み取ります:
grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method <<EOM
{
"id": 1234,
"tags": [
"foo",
"bar"
]
}
EOM
リクエストへのヘッダー/メタデータの追加
-H name:value コマンドラインオプションを使って、RPC リクエストにヘッダー/メタデータを追加できます。同様の方法で複数のヘッダーを追加できます。
例:
grpcurl -H header1:value1 -H header2:value2 -d '{"id": 1234, "tags": ["foo","bar"]}' grpc.server.com:443 my.custom.server.Service/Method
使用方法の詳細は、grpcurl -help でヘルプドキュメントを確認してください。
サービスの一覧表示
サーバーが公開しているすべてのサービスを一覧表示するには、"list" 動詞を使用します。サーバーリフレクションの代わりに .proto ソースまたは protoset ファイルを使用する場合は、ソースまたは protoset ファイルで定義されているすべてのサービスが一覧表示されます。
# Server supports reflection
grpcurl localhost:8787 list
# Using compiled protoset files
grpcurl -protoset my-protos.bin list
# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto list
# Export proto files (use -proto-out-dir to specify the output directory)
grpcurl -plaintext -proto-out-dir "out_protos" "localhost:8787" describe my.custom.server.Service
# Export protoset file (use -protoset-out to specify the output file)
grpcurl -plaintext -protoset-out "out.protoset" "localhost:8787" describe my.custom.server.Service
"list" 動詞を使うと、特定のサービスに含まれるすべてのメソッドも確認できます:
grpcurl localhost:8787 list my.custom.server.Service
要素の説明
"describe" 動詞は、サーバーが認識している、または指定した protoset ファイル内にある任意のシンボルの型を出力します。また、そのシンボルの説明を proto ソースの断片として出力します。必ずしも要素を定義した元のソースとは限りませんが、同等の内容です。
# Server supports reflection
grpcurl localhost:8787 describe my.custom.server.Service.MethodOne
# Using compiled protoset files
grpcurl -protoset my-protos.bin describe my.custom.server.Service.MethodOne
# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto describe my.custom.server.Service.MethodOne
ディスクリプターのソース
grpcurl ツールは、さまざまなディスクリプターソースを使用できます。RPC スキーマを grpcurl が理解し、入力を protobuf のバイナリ形式に変換するとともに、応答をバイナリ形式からテキストに変換するために、ディスクリプターが必要です。以下のセクションでは、サポートされているソースと、それらを使用するために必要なコマンドラインフラグについて説明します。
サーバーリフレクション
追加のコマンドラインフラグを指定しない場合、grpcurl はサーバーリフレクションを使用しようとします。
サーバーリフレクションの設定方法の例は、こちらで確認できます。
リフレクションを使用する場合、「list」および「describe」操作でもサーバーアドレス(ホスト:ポート、または Unix ソケットのパス)が必要です。grpcurl がサーバーに接続して、そのディスクリプターを取得するためです。
Proto ソースファイル
リフレクションをサポートしていないサーバーで grpcurl を使用するには、.proto ソースファイルを使用できます。
-proto フラグを使用して、関連する Proto ソースファイルを grpcurl に指定するほか、依存関係をインポートするフォルダーを grpcurl に伝えるために、-import-path フラグも指定する必要がある場合があります。
protoc でコンパイルする場合と同様に、protoc に含まれる標準 Proto の場所のインポートパスを指定する必要はありません(これらのファイルには、google.protobuf のパッケージ定義を持つさまざまな「well-known types」が含まれています)。これらのファイルのディスクリプターのスナップショットは grpcurl バイナリに組み込まれているため、grpcurl はこれらのファイルを認識します。
Proto ソースを使用する場合、「list」および「describe」操作では Proto ソースファイルのみを参照すればよいため、サーバーアドレス(ホスト:ポート、または Unix ソケットのパス)を省略できます。
Protoset ファイル
grpcurl では、コンパイル済みの Protoset ファイルも使用できます。grpcurl をスクリプトから実行し、同じ Proto ソースを複数回の呼び出しで再利用する必要がある場合は、Protoset ファイルを使用するとパフォーマンスが向上します(呼び出しのたびに解析とコンパイルを行う必要がなくなるためです)。
Protoset ファイルには、バイナリ形式でエンコードされた google.protobuf.FileDescriptorSet Proto が含まれています。Protoset ファイルを作成するには、サービスを定義する *.proto ファイルを指定して protoc を実行します。
protoc --proto_path=. \
--descriptor_set_out=myservice.protoset \
--include_imports \
my/custom/server/service.proto
--descriptor_set_out 引数は protoc に Protoset を生成させるためのもので、--include_imports 引数は grpcurl がスキーマを処理して理解するために必要なすべての情報を Protoset に含めるために必要です。
Protoset を使用する場合、「list」および「describe」操作では Protoset ファイルのみを参照すればよいため、サーバーアドレス(ホスト:ポート、または Unix ソケットのパス)を省略できます。