REST <-> gPRC汎用ゲートウェイ書いた
Openresty1.15.8.1、nginxが1.15系が入っててgPRC-proxyできるようになって最強感あるので早くRC取れてほしいな!
— Yoshiaki Sugimoto (@sugimoto1981) 2019年4月17日
ということで、Openresty1.15.8.1rc1からはNginx-Coreに1.15.0を使うようになっていて、すなわちgRPC-webのproxyができるようになる。
See also: OpenResty 1.15.8.1 RC1 is out
REST to gRPCできたら最高だけど流石に標準では出来なさそう。まぁLuaで実装すればいいのか。
— Yoshiaki Sugimoto (@sugimoto1981) 2019年4月17日
というわけで作った。
ysugimoto/lua-resty-grpc-gateway
nginx.confで普通に定義したlocationのエンドポイントをgPRCリクエストに変換してbackendに流し、受け取ったレスポンスをJSONに変換して返すという、所謂REST to gPRCができるgatewayライブラリ。
今までは grpc-gateway を使うことでできたんだけど、これを使う==Goを選択せざるを得なかったわけだけど、これを使うことでnginxのレイヤーで処理できるようになる。 で、grpc-gatewayを使う==バックエンドもGoで書くだろうけど、gatewayを分離することでgPRCサーバは他の言語で実装しても良いので選択肢は広くなるんじゃないかなって思う。PHPとかJSとか。
まぁ代わりにLua書くはどうなのよってのもあるけど、HTTPサーバのレイヤで処理ができるということはbackendのマイグレーションも比較的簡単になって、特定のエンドポイントをRESTからgPRCに変更するのもシームレスにできる。
とはいえインストールしてはい完了ってわけには行かず、3つのフックポイントを使って変換処理を書かないといけない、protoファイルをnginxサーバにバンドルしないといけないなどはあるが、イマドキならコンテナで動かすケースも多いからイメージビルドするときに入れちゃえば良くてそこまでハードルは高くないのかも。
詳しい使い方はREADMEを見てください。実際に動かせるexampleも置いてあるので動かしてみて頂けると。
まとめ
もともとはgrpc-webをちゃんと評価してみようってことで始めたけど、結果としてRESTも扱えるようになったことでgPRCの採用ケースは増やせそうな気がしている。
gRPCはprotocol buffersでリクエストの形式を定義できる点が良いと思っていて、クライアント->バックエンドの通信にgraphQLを採用したりしていたけど、grpc-webでも良さそうな気がしている。
あと、Openresty(nginx)レイヤーでやる意味もちゃんとあって、
- upstreamセクションにgrpcサーバを列挙することでRoundrobinできる
- ヘッダ制御もここで行うことで、CDN、例えばFastlyとかの配下とのキャッシュ戦略もこのレイヤーで完結させ、アプリケーションはその一切を気にしなくて良い
- envoyみたいに特定のヘッダでルーティングをCanaryに流すとかもできる。Luaでscriptingするならもっと複雑なことも
- レスポンスのキャッシュもresty-redisでここのレイヤーでやるとかも
と、まさにHTTP gatewayの役割をきちんと分離できる。OpenrestyのコンテナをアプリケーションのSide carとして起動すると使い勝手良さそう。
サクッと書いて公開したものなのでまだちょっとバグあるかもしれません。使ってみてPRなど頂けると嬉しいです。 あと早くRC取れてstableになってほしいなぁ。
現場からは以上です。