Edited at

gRPC UIを使ってみんなが触れるgRPCの遊び場を作りました

gRPCは近年非常によく使われるようになったRPCフレームワーク1ですが、その柔軟なメッセージフォーマットに対応するリッチなGUIクライアントに欠けていました。REST APIでいうPostman的な存在です。このようなツールがなければgRPCを利用した開発が面倒なのですが、その問題は現在においてはほぼ払拭されたといっても過言ではありません。gRPC UIが登場したからです。

(本記事は自分のブログからの転載記事です。)

(2019/10/4 追記)

gRPC UI playgroundの運用に利用していたArukasが2020年1月31日でサービス終了するようです。今後gRPC UI playgroundをどうするかは検討中です。


TL;DR


  • gRPC UIで作成した遊び場はこちらです :point_right: gRPC UI playground

  • gRPC UIはgRPCサーバへの要求と応答がWebで簡単にできるので、今後のgRPCを利用した開発に広く使われるツールとなりそうです

  • gRPC UI playgroundは以下のサービスを利用して、無料で立ち上げました。当面はみんなが遊べるようにしておくつもりです



  • gRPC UI playgroundの運用に利用していたArukasが2020年1月31日でサービス終了するようです。今後gRPC UI playgroundをどうするかは検討中です


はじめに

本記事はgRPCのWeb UIであるgRPC UIの紹介記事です。gRPCに興味がある方、gRPCを利用している方を対象にしています。実際にgRPC UIを触れる遊び場も作ったのでgRPCに興味がある方は遊んでいってください。また本記事ではこの遊び場をどうやって作ったのかも簡単に解説します。


gRPCとは

gRPCはGoogleが開発してオープンソースとして公開したRPCフレームワークです。IDL2としてProtocol Buffers3が利用可能です4。gRPCは基本的には以下の図ように単純で、クライアントから要求(Proto Request)を送ってサーバが応答(Proto Response)を返すというものです。クライアントやサーバの記述には、Protocol Buffersが対応している様々な言語(C++, Ruby, Java等)が利用可能です。

What is gRPCより引用

gRPCは上記のように単純な要求/応答型以外にも様々なやりとりに対応できます。具体的には以下の4つです。


  • Unary RPC(単純な要求/応答型)

  • Server streaming RPC(サーバが複数の応答を返すことができる)

  • Client streaming RPC(クライアントが複数の応答を返すことができる)

  • Bidirectional streaming RPC(クライアントとサーバがそれぞれ複数の要求/応答ができる。一般的な双方向通信)

上記のような柔軟な呼び出しはHTTP/25の基盤に支えられて実現されています。


gRPC UIについて

gRPC UIはgRPCサーバとブラウザでやりとりできるツールです。百聞は一見にしかず。以下の画面を御覧ください。

この画面を見て震えたのはやはり要求の入力画面(Request Form)の充実っぷりです。gRPCは自分でデータの型を定義して入れ子のようなメッセージを定義できますが、そのような入力も簡単にできます。上記の図のではtest.TestMessageというメッセージの中にperson(test.Personというメッセージの型)が内包されています。また複数のデータが入力可能なフィールドは「Add Item」で簡単に追加できます。その他の注目すべき点は赤字で説明を入れておいたので参考にしてください。基本的にはgRPC(Protocol Buffers)で定義されている入力形式はほぼ網羅されています。

また、驚いたのはgRPCには基本的なスカラ値(stringint64等)以外にも「Well-Known Types」と呼ばれる型が定義されていますが、gRPC UIにはこれらにもリッチなインタフェースが提供されていたことです。以下の画面はtimestamp型に対するインタフェースです。

またリッチなフォームだけではなく、JSON形式でリクエストを投げることもできます。

JSON形式で便利なのはコピペが容易なところです。また省略されているフィールドは出力されないので見やすくなります。フォーム型の編集画面とも連動しているので、非常に使いやすいです。リクエストは「Invoke」ボタンを押すことでサーバに投げることができます。このボタンはフォーム型のリクエストにも一番下にあります。以下が「Invoke」を押して返ってきた応答になります。

この画面も特に説明がいらないくらい分かりやすいものになっています。gRPC UIで対応できないのは双方向の複雑なやり取りです。これは従来どおりCUI等を利用して行うしかありません。


gRPC UIで遊ぼう! 〜 gRPC UI playground 〜

さて、ここまで来たらgRPC UIで遊んでみたくなったと思います。以下にみんなが遊べるように「遊び場」を立ち上げたのでぜひいろいろ遊んでみてください。

gRPC UIはバックグラウンドで起動しているgRPC UIのテストサーバ(testsvr)とやりとりしています。プロトコルは「test.proto」、サーバの実装は「testsvr.go」に記述されています。実際にgRPC UIを動かしながらソースやIDLを読むとgRPCの理解が深まると思います。

メソッドに関しては「DoManyThings」が全部詰めになっていて、残りのメソッドはそれを機能単位で分割したものになっています。たぶん・・・


grpcui-playgroundの作り方

さて、ここからはおまけです。上記の遊び場(以降、grpcui-playgroundと記載)の構築方法の興味がある方を対象に簡単に説明したいと思います。grpcui-playgroundは3つのサービスを利用して無料で立ち上げました。以下がその構成になります。

上の図をざっくり説明すると、基本的にはDockerを使ってサービス提供しています。一つのコンテナの中にgPPC UIとgRPC Server(testsvr)という二つのプロセスが動いています。一つのコンテナに二つのプロセスはあまりお行儀がよくありませんが、今回は遊び場ということと無料で立ち上げることを重視したのでこのような構成になっています。

利用したコンテナホスティングサービスはArukas6になります。今回はFreeプランを利用しています。Arukasにコンテナイメージを提供するためにはDocker Hubも利用しました。Docker HubにはGitHubと連携しておくとGitHubの変更を検知してコンテナをビルドする機能があるのでそれも利用しています。


Dockerfileを書く

Dockerfileを書くときの注意点は二つです。まず、ビルドイメージを小さくするためにAlpine Linux7をベースイメージにします。次にgRPC UIが提供しているテストサーバ(testsvr)はgoで書かれているのでgoのビルド環境が必要です。ただしgoのビルド環境は動作には必要ないのでマルチステージビルドを活用して、なるべく小さなイメージにするようにしましょう8


Dockerfile

FROM golang:1.12.7-alpine as build-env

MAINTAINER hinastory

WORKDIR /testsvr
COPY testsvr /testsvr

RUN apk update && apk add --no-cache git

RUN go build

RUN go get -x github.com/fullstorydev/grpcui
RUN go install -x github.com/fullstorydev/grpcui/cmd/grpcui

FROM alpine
WORKDIR /
COPY --from=build-env /testsvr/testsvr /bin/testsvr
COPY --from=build-env /go/bin/grpcui /bin/grpcui
COPY start.sh /start.sh

EXPOSE 8080

ENTRYPOINT [ "/start.sh" ]



GitHubでDockerfileを公開する

ここは特に説明はしませんが、GitHubに公開レジストリを作成し、Dockerfileとtestsvrのソースと起動スクリプトをpushします。pushした自分のリポジトリは以下になります。










Docker Hubでイメージをビルド & 公開する

Docker Hubでイメージをビルドするのには、GitHubと連携しておいたほうが楽です。GitHubと連携しておけばGitHubのレポジトリをDocker HubのUIから選択できるようになり、GitHubにpushするだけでDockerfileをビルドしてくれるようになります。

注意すべき点はDockerイメージのタグの付け方です。デフォルトだとブランチを監視してlatestタグを付けるようになっていますが、Arukasはイメージをキャッシュする場合があるようなのでバージョンが入った適切なタグをつけることが望ましいです。そしてDockerのイメージタグはGitHubのタグと連動しているとよいと思われます。

Docker Hubでその設定をするのは簡単でDockerHubのリポジトリのBuildsの画面からビルドルールを設定でき、Source TypeTagにして、SourceDocker Tagを正規表現で記述することでお望みのタグが構成できると思います。またここでDockerfileの位置やビルドコンテキストも指定可能なので、少し複雑なリポジトリ構成でも対応出来ます。

ここの設定が終わったらGitHubにタグをpushしてビルドが始まるか確認します。基本的には検知はすぐに行われてIn Progressの状態にすぐに変わりますがビルドが終わるまでには時間がかかるので、コーヒーでも飲んでまったりと待ちましょう(笑)。自分のコンテナイメージは以下に公開してあります。


ArukasでDockerコンテナを公開する

最後にArukasuでコンテナを公開します。FreeプランはO.1vCPUと128MB RAMの非力な環境ですが、今回のような遊び場には充分だと思われます。また「転送量課金」がないのでDDoSとかの心配がまったくいらないのも嬉しいところです。もちろん最悪サービスは落とされますが、料金に怯える心配は無いわけです。ちなみにFreeプランでも電話認証とクレジットカードの登録は必須です。このアカウント登録が最大の難関でコンテナの起動は驚くほどあっけなく終わりました。アプリ起動の詳細は「アプリの作成 – Arukas Help Center」を参照してください。以下は起動したコンテナの管理画面です。Endpointはアプリの再起動で変わることが無いURLです。Portはインスタンスの起動毎に変わります。ちなみにgRPC UIは8080ポートでHTTPでサービスを公開していますが、エンドポイントではHTTPSになっているので自動でArukasがHTTPSに包んでくれるみたいです。


まとめ

本記事では、gRPCサーバとブラウザでやり取りできるgRPC UIを紹介しました。gRPC UIは非常に便利なので今後gRPC関連の開発で広く使われていくものと思われます。そして実際にgRPC UIを触れる遊び場を作成して以下に公開しました。

また、おまけとしてその遊び場の作り方を(無料でコンテナサービスを立ち上げる手順)を簡単に説明しました。

本記事がgRPCを理解し、より便利に使えるようになるための一助になれば幸いです。


参考文献





  1. RPC(Remote Procedure Call)は、簡単に言えばプログラムの中から内部の関数を呼ぶのと似たような感覚で、外部のネットワーク上の関数や手続きを呼べるようにする技術のことです。他のRPCにはSOAPやJSON-RPCなどがあります。 



  2. IDLはインタフェース記述言語(Interface Description Language)のことです。簡単に言えば関数呼び出しの宣言部分を定義する際に使う言語です。 



  3. Protocol BuffersはGoogleが開発したシリアライズフォーマットです。IDLは独自の言語でシンプルで分かりやすいのが特徴です。IDLのファイルは.protoの拡張子を持っており、protocというコンパイラを用いてIDLファイルからGo言語やRuby、Python、Java等様々な言語のバインディングを生成できます。現在のProtocol Buffersのバージョンは3になります。 



  4. JSONも利用可能みたいですが、自分は使ったことはありません。 



  5. HTTP2はHTTP/1.1の後継バージョンでRFC7540で定義されています。HTTP/1.1と比べてヘッダーの圧縮やバイナリメッセージ構造、双方向通信のサポート等様々な改善がなされています。 



  6. Arukasはさくらインターネットが提供しているDockerのホスティングサービスです。Arukasを反対から読むと・・・ 



  7. Alpine Linuxは軽量、シンプル、セキュアをコンセプトにしたLinuxディストリビューションです。組み込み系で実績のあるmusl libcとbusyboxをベースにしています。その軽量さからコンテナのベースイメージとしてよく利用されています。 



  8. 最初は無邪気にベースイメージをstretchにしてシングルステージでビルドしたため、イメージのサイズが400MBを超えてしまいました・・・現在のサイズは 18MBです。特にパブリックなレジストリに登録する際はコンテナイメージのサイズに充分気を配り、リソースを無駄にしないように心掛けましょう(自戒)。