All Articles

OpenrestyでgRPCをRESTから実行できるライブラリ書いた

REST <-> gPRC汎用ゲートウェイ書いた

ということで、Openresty1.15.8.1rc1からはNginx-Coreに1.15.0を使うようになっていて、すなわちgRPC-webのproxyができるようになる。

See also: OpenResty 1.15.8.1 RC1 is out

というわけで作った。

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になってほしいなぁ。

    現場からは以上です。