1
1

More than 1 year has passed since last update.

grpcurlで快適gRPC通信テスト

Last updated at Posted at 2021-08-16

経緯

goで作っているサービスのgRPC通信の動作確認用にgrpcurlというクライアントツールを使ってみました。

別クライアントのgrpc_cliはMacローカルにbrewでインストールしてもうまくパスが通らず諦めました。

環境

$ sw_vers
ProductName:    macOS
ProductVersion: 11.5.1
BuildVersion:   20G80
$ go version
go version go1.16.6 darwin/arm64
$grpcurl --version
grpcurl 1.8.2

インストールはおもむろに brew install grpcurl で行いました。

手順

1. サーバーを立ち上げる

$ cd $GOPATH/src/github.com/hoge-monorepo
$ go run cmd/xxxx/main.go
{"level":"INFO","ts":"2021-08-16T16:33:21.649229+09:00","caller":"auth/main.go:81","function":"main.runGRPCServer","message":"Start GRPC server at [::]:50051, TLS = false","hostname":"XXXs-M1-MacBook-Pro.local"}

*xxxxはサービス名

2. 利用可能なサービス一覧を確認する

$ grpcurl localhost:50051
Failed to dial target host "localhost:50051": tls: first record does not look like a TLS handshake

あれ?

$ grpcurl --help
...
-plaintext
        Use plain-text HTTP/2 when connecting to server (no TLS).
...

TLS無しのアクセス時には-plaintextは必須。ということで

$ grpcurl -plaintext localhost:50051 list
grpc.reflection.v1alpha.ServerReflection
proto.AuthManagement

$ grpcurl -plaintext localhost:50051 describe
grpc.reflection.v1alpha.ServerReflection is a service:
service ServerReflection {
  rpc ServerReflectionInfo ( stream .grpc.reflection.v1alpha.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1alpha.ServerReflectionResponse );
}
proto.AuthManagement is a service:
service AuthManagement {
  rpc Login ( .proto.LoginRequest ) returns ( .proto.LoginResponse ) {
    option (.google.api.http) = { post:"/auth/v1/login" body:"*"  };
  }
  rpc VerifyToken ( .proto.VerifyTokenRequest ) returns ( .proto.VerifyTokenResponse ) {
    option (.google.api.http) = { put:"/auth/v1/verify-token" body:"*"  };
  }
}

これで、このAPIが露出している全てのサービスall exposed servicesを出力できました。
(gRPCのmethodは全てPOSTなので、通常のcURLのように-X POSTのような指定は不要です。)

3-1. 実際にAPIコールしてみる

$ grpcurl -plaintext localhost:50051 list proto.AuthManagement
proto.AuthManagement.Login
proto.AuthManagement.VerifyToken

$ grpcurl -plaintext -d '{"email": "hoge@example.com", "password": "1234"}' localhost:50051 proto.AuthManagement/Login
{
  "data": {
    "access_token": "eyJhbGciOi......",
    "refresh_token": "eyJhbGciOi......"
  }
}

3-2. リクエストパラメータを標準入力で入れたい場合

$ grpcurl -plaintext -d @ localhost:50051 proto.AuthManagement/Login
(ここで標準入力の待ち受けモードとなるので、おもむろにJSONをペースト。)
{
"email": "hoge@example.com",
"password": "1234"
}
(ここで「control + D」を押して終了。)
{D
  "data": {
    "access_token": "eyJhbGciOi......",
    "refresh_token": "eyJhbGciOi......"
  }
}

3-3. より詳細な情報を標準出力に表示したい場合

-v-vvで出力が冗長(verbose)になります。

$ grpcurl -v -plaintext -d '{"email": "hoge@example.com", "password": "1234"}' localhost:50051 proto.AuthManagement/Login

Resolved method descriptor:
rpc Login ( .proto.LoginRequest ) returns ( .proto.LoginResponse ) {
  option (.google.api.http) = { post:"/auth/v1/login" body:"*"  };
}

Request metadata to send:
(empty)

Response headers received:
content-type: application/grpc

Response contents:
{
  "data": {
    "access_token": "eyJhbGciOi......",
    "refresh_token": "eyJhbGciOi......"
  }
}

Response trailers received:
(empty)
Sent 1 request and received 1 response

以上、簡単に説明してきました。
他にも特殊なAPIコールの仕方が出てきたら追記したいと思います。

以下、2021.10.28追記

4. import pathを指定する場合

protoファイルを指定してgRPCコールを試す際に、protoファイル中のimport文がうまく動かないことがあります。

例えば以下のようなファイルがあったとします。

$ tree -L 3 ./proto
proto
├── google
│   └── api
│       ├── annotations.proto
│       ├── http.proto
│       └── httpbody.proto
└── account
    ├── auth_management_service.proto
    └── auth_message.proto
3 directories, 5 files
proto/account/auth_management_service.proto
syntax = "proto3"

package proro;

import "google/api/annotations.proto"; <------ import先参照不可エラー
import "auth_message.proro"; <------ import先参照不可エラー

option go_package = ".;account";

service AuthManagement {
  rpc Login(LoginRequest) returns (LoginResponse) {
    option (google.api.http) = {
      post : "/v1/login"
      body : "*"
    }
  }
}

この状態で徐にgrpcurlコマンドを叩くと、

grpcurl -plaintext \
 -d '{"email": "hoge@example.com", "password": "1234"}' \
 -proto account/auth_management_service.proto \
 127.0.0.1:8011 \
 proto.AuthManagement/Login

Failed to process proto source files.: could not parse given files: open account/auth_management_service.proto: no such file or directory

と怒られてしまいます。


ここでgrpcurlコマンドに-import-path ./protoオプションをつけると、

grpcurl -plaintext \
 -d '{"email": "hoge@example.com", "password": "1234"}' \
 -import-path ./proto \
 -proto account/auth_management_service.proto \
 127.0.0.1:8011 \
 proto.AuthManagement/Login

Failed to process proto source files.: could not parse given files: account/auth_management_service.proto:6:8: open proto/auth_management.proto: no such file or directory

となります。そのため、account/フォルダの場所を明示的に示してあげる必要があります。


-import-path ./proto/accountを追加します。

grpcurl -plaintext \
 -d '{"email": "hoge@example.com", "password": "1234"}' \
 -import-path ./proto \
 -import-path ./proto/account \
 -proto account/auth_management_service.proto \
 127.0.0.1:8011 \
 proto.AuthManagement/Login

Failed to process proto source files.: could not parse given files: account/auth_message.proto:6:8: open proto/validate/validate.proto: no such file or directory

このvalidate/validate.protoというのはバリデーションのためのprotocプラグインで、このプロジェクト配下に存在するものではなく、ご自身のGOPATH配下のパスを指定する必要があります。

$ go get -d github.com/envoyproxy/protoc-gen-validate

これでご自身のGOPATH配下にprotoc-gen-validateが無事インストールされます。


-import-path ${GOPATH}/src/github.com/envoyproxy/protoc-gen-validateを追加します。

grpcurl -plaintext \
 -d '{"email": "hoge@example.com", "password": "1234"}' \
 -import-path ./proto \
 -import-path ./proto/account \
 -import-path ${GOPATH}/src/github.com/envoyproxy/protoc-gen-validate \
 -proto account/auth_management_service.proto \
 127.0.0.1:8011 \
 proto.AuthManagement/Login

{
  "data": {
    "access_token": "eyJhbGciOi......",
    "refresh_token": "eyJhbGciOi......"
  }
}

これで無事、import文の参照切れがなくなりAPIコールが正しく通るようになりました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1