はじめに
「gRPCサーバーを建てたけど、クライアントからどうやってリクエストするのがいいの?」
という人向けに、gRPCクライアントをいろいろ試した結果をまとめた。
TL;DR
gRPCクライアントはいろいろあるので、以下のように用途に合わせて使う。
- とにかく一番簡単な方法でリクエストする -> grpcc
- ブラウザからgRPCライクにリクエストする -> gRPC Web
- RestAPIライクにリクエストする -> Google Cloud Endpoints または gRPC Gateway
前提
- gRPCサーバーはlocalhostの6565ポートでアクセス可能とする
- 以下のようなprotoファイルで定義されたサーバーにアクセスする
syntax = "proto3";
service Person {
rpc GetPersons ( Empty ) returns ( PersonsModel ) {}
}
message Empty {}
message PersonModel {
string name = 1;
int32 id = 2;
}
message PersonsModel {
repeated PersonModel person = 1;
}
とにかく一番簡単な方法でリクエストする
grpccを使う。
似たようなツールにgRPC command line toolというのもあるが、ドキュメントを見た感じだとgrpccのほうが洗練されてそう。(gRPC command line toolも試したら追記する。)
特徴
- コード不要。インストールするだけですぐ使える。
- 開発時のテストとして使ったりするのに良い。
- 対話モードでは補完が効くのも素晴らしい。
使い方
対話モードで呼び出す
# protoファイルと接続先gRPCサーバーを指定し、対話モードで起動
$ grpcc --proto ./person.proto --address 127.0.0.1:6565 -i
# getPersonsを呼び出し
$ Person@127.0.0.1:6565> client.getPersons({}, printReply)
対話モードではなく直接呼び出す場合
# --evalオプションで実行するコマンドを指定
$ grpcc --proto ./person.proto --address 127.0.0.1:6565 -i --eval 'client.getPersons({}, printReply)'
{
"person": [
{
"name": "Ranga",
"id": 10001
},
{
"name": "Ravi",
"id": 10002
}
]
}
参考
ブラウザからgRPCライクにリクエストする
gRPC Webを使う。
特徴
- 生成したTypeScriptのコードを使えばクライアント側にも型を強制できる。
- 実際にはhttp/1.1でアクセス。
- クライアントとサーバー間に別途grpcwebまたはgRPC WebProxyが必要。
- サーバーがgoの場合はgrpcwebを使う
- それ以外の場合はgRPC WebProxyを使う
使い方
protoファイルからコード生成
$ PROTOC_GEN_TS_PATH="./node_modules/.bin/protoc-gen-ts"
$ OUT_DIR="./src/generated"
$ protoc \
--plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \
--js_out="import_style=commonjs,binary:${OUT_DIR}" \
--ts_out="service=true:${OUT_DIR}" \
--proto_path="../protofiles" \
person.proto
生成したコードを使ってTypeScriptで処理を書く
import {grpc} from "grpc-web-client";
import {Empty} from "../../generated/person_pb";
import {Person} from "../../generated/person_pb_service";
getPersons() {
const empty = new Empty()
grpc.unary(Person.GetPersons, {
request: empty,
host: "http://localhost:8080",//gRPC WebProxyを使う場合は、gRPC WebProxyのURLを指定する
onEnd: res => {
const {status, statusMessage, headers, message, trailers} = res
if (status === grpc.Code.OK && message) {
console.log(message.toObject())
}
}
})
}
gRPCサーバーがgoの場合は、grpcwebでラップする。
それ以外の場合は、以下のようにgRPC WebProxyを起動する。 (今回はDockerで起動)
$ docker run -p 8080:8080 --rm -it jfyne/docker-grpcwebproxy /grpcwebproxy --backend_addr=host.docker.internal:6565 --run_tls_server=false
参考
https://github.com/improbable-eng/grpc-web/tree/master/ts
https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy
RestAPIライクにリクエストする
Google Cloud Endpoints または gRPC Gatewayを使う。
特徴
- エンドポイントに対応するURLを設定することでRestAPIライクにリクエストできる。
- gRPC Web が使えない事情がある場合、ブラウザからリクエストするにはこちらを使う。
使い方
今回検証した Google Cloud Endppoints と Google Kubernetes Engine を連携させるパターンのみ記載する。
Endpoints設定ファイルを作成。ここでエンドポイントのURLを設定する
type: google.api.Service
config_version: 3
name: person.endpoints.[GOOGLE_PROJECT_ID].cloud.goog
title: person gRPC API
apis:
- name: Person
http:
rules:
- selector: Person.GetPersons
get: /v1/persons
usage:
rules:
- selector: "*"
allow_unregistered_calls: true
Endpoints設定をデプロイする。
$ protoc --include_imports --include_source_info person.proto --descriptor_set_out out.pb
$ gcloud endpoints services deploy out.pb api_config.yaml
あとはチュートリアルの通り進める。