gRPCサーバーの動作確認をgrpcurlでやってみた

## はじめに
gRPCサーバーの動作確認どうしよう。。。と色々調べてたどり着いたgrpcurlをご紹介。
色々機能はあるようですが、一部だけの紹介になります。

**確認した環境**

gRPCサーバーの構成

- Spring Boot 1.5.10
- grpc-spring-boot-starter 2.4.0

開発環境

- Windows

## grpcurlとは

https://github.com/fullstorydev/grpcurl
gRPCサーバーとの対話をcurlコマンドライクに実現できるツールです。
コマンドを実行するとgRPCサーバーの応答がjson形式で返ってきます。

リンク先に詳細が書かれていますのでそちらを読むだけでもいいかと思います。

なお、goのインストールが必要です。

## 準備（Windows編）

### 1. Goのインストール

**ダウンロード～インストール**
https://golang.org/dl/
こちらのサイトから皆さんの環境にあったものをダウンロードしてください。
Windowsの場合、インストーラーの指示に従えば特に問題なく完了できます。

**設定の確認**
Windowsの場合、環境変数に以下のものが追加されています。
* GOPATH：%USERPROFILE%go
* GOROOT：インストール時に指定したディレクトリ
* Path：%GOPATH%binが追加されます。


**インストール確認**

コマンドプロンプトでgo versionとタイプしバージョン情報が表示されればインストール完了です。

```console
> go version
```

※実行できない方はコマンドプロンプトを再起動するか、システム環境変数のPathを確認しましょう。

### 2. grpcurlのインストール

**ダウンロード～インストール**

下記のコマンドを実行するだけでOKです。

```console
> go get github.com/fullstorydev/grpcurl
> go install github.com/fullstorydev/grpcurl/cmd/grpcurl
```
先ほど確認した、$GOPATH 環境変数に指定した場所のbinサブフォルダにgrpcurlコマンドがインストールされます。
デフォルトであればPathには%GOPATH%binが指定されているのでコマンドプロンプトからすぐに実行できるはずです。
実行できない方はPathの指定を確認してみてください。

**インストール確認**

下記のコマンドが実行できればgrpcurlのインストールは完了です。

```console
> grpcurl -help 
```

### 3. reflection の設定

gRPCサーバーでreflection機能を有効にします。
※ grpcurlではreflectionが有効ではない場合の実行方法も用意されていますが今回は割愛。:sweat_smile:

grpc-spring-boot-starterを利用している場合、application.ymlに下記の設定を追加するだけでOKです。

```yml:application.yml
grpc:
  enable-reflection: true
```
注意：grpc-spring-boot-starterのバージョンによっては対応していません。（2.3.2～）

starterを利用していない場合は下記の手順で行けるようです。（未確認）
https://github.com/grpc/grpc-java/blob/master/documentation/server-reflection-tutorial.md


これで準備は完了です。

## TODO 準備（Mac編）
 // coming soon ...

## 使ってみる

動作確認する対象のgRPCサーバーを起動しておきます。

### サービス一覧を表示

```console
> grpcurl -plaintext localhost:6565 list
```

-plaintext
　plain-textモードで動作確認ができます。
　省略するとTLSで確認できます。

localhost:6565
　gRPCサーバーのホスト名とポート番号を指定します。

実行すると、下記のようにサーバー側にあるサービス一覧が表示されます。

```console:実行結果
> grpcurl -plaintext localhost:6565 list
helloworld.HelloWorldService
goodbyeworld.GoodByeWorldService
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection
```

### メソッド一覧の表示

```console
> grpcurl -plaintext localhost:6565 list helloworld.HelloWorldService
```
helloworld.HelloWorldService
　サービス一覧を取得するコマンドの後ろにサービス名を指定します。

```console:実行結果
> grpcurl -plaintext localhost:6565 list helloworld.HelloWorldService
Greeting
```

### サービスの呼び出し

```console
> grpcurl -plaintext localhost:6565 helloworld.HelloWorldService/Greeting
```

helloworld.HelloWorldService/Greeting
　一覧で確認したサービス名/メソッド名を指定します。

実行すると結果がjson形式で表示されます。

```console:実行結果
> grpcurl -plaintext localhost:6565 helloworld.HelloWorldService/Greeting
{
  "message": "Hello World!"
}
```

### サービスの呼び出し(リクエストパラーメータあり)

``` console
> grpcurl -plaintext -d '{"lang":"Java"}' localhost:6565 helloworld.HelloWorldService/Greeting
```
-dの後にjson形式でパラメータを記載すればいい。
と、サイトには書かれていたのですが、シングルクォートが怒られたりとうまく動きませんでした:cold_sweat:。
そこで。。。

```console
> grpcurl -plaintext -d @ localhost:6565 helloworld.HelloWorldService/Greeting
```
-dのあとに'@'を指定することでSTDINでパラメータを入力できる、という方法が紹介されていたのでこちらを試しました。

```console
> grpcurl -plaintext -d @ localhost:6565 helloworld.HelloWorldService/Greeting
{
  "lang": "Java"
}
EOM
```

EOM
　WindowsではCtrl+Z、Unix系ではCtrl+Dで入力できます。
　Windowsのコマンドプロンプトでは`^Z`で表示されます。

実行すると見事に結果が返ってきました。:relaxed:

```console:実行結果
> grpcurl -plaintext -d @ localhost:6565 helloworld.HelloWorldService/Greeting
{
  "lang": "Java"
}
^Z
{
  "message": "Hello Java World!"
}
```

### おまけ

結果をファイル出力したい場合はこんな感じ。

``` 
grpcurl -plaintext localhost:6565 helloworld.HelloWorldService/Greeting > GreetingResult.json
```

```json:GreetingResult.json
{
  "message": "Hello World!"
}

```

おわり