時計を壊せ

駆け出してからそこそこ経ったWebプログラマーの雑記

Google App Engineでローカル開発をするときにdispatch.yamlをもとにReverse Proxyしてくれるツールを書いた

これです

github.com

なぜ作ったのか

dispatch.yamldispatch.xml はGoogle App Engine(以下GAE)のFrontendでルールベースでL7 HTTP Reverse Proxyしてくれるものです。

cloud.google.com

これはMicroservicesをやる上では大変便利なものになっています。
一方で、これをローカルで動かす手段が少なくとも自分の知る限りはありませんでした。

なので、いままでは各サービスを連携して動作検証したいときは、GAEにデプロイしてしまうか、
あるいは各サービスをそれぞれ別々のポートで立ち上げながら、各サービスに何らかの方法でそれらのマッピング情報を入れてサービス間で連携が可能なようにするなど工夫をする必要がありました。

別々のポートで立ち上げるところまではよしとしても、めんどくさいのでその後の各サービスには統一的にアクセスしたいわけです。
しかし、dispatch.yamldispatch.xml をnginx.confなどに移植してnginxを立ち上げたりなんてのもまためんどくさい。ぐぬぬ。

せめて dispatch.yamldispatch.xml をそのまま読んでよしなにReverse Proxyしてくれるサーバーがあると楽そうです。 ということで作りました。

使い方

README.mdにあるとおりですが、こういう感じで使えます。

$ (cd default; dev_appserver.py --port=8081 | tee -a dev.log) &
$ (cd mobile-backend; dev_appserver.py --port=8082 | tee -a dev.log) &
$ (cd static-backend; dev_appserver.py --port=8083 | tee -a dev.log) &
$ gae-dispatcher-emulator -c dispatch.yaml -s default:localhost:8081 -s mobile-frontend:localhost:8082 -s static-backend:localhost:8083

-c で渡した dispatch.yaml-s で渡しているサービスの待受情報をもとによしなにやってくれるというわけです。

これでデフォルトの localhost:3000gae-dispatcher-emulator

実際はforemanなどと組み合わせて使うのがおすすめです。

インストール

go製なので go get でいけます。

$ go get -u github.com/karupanerura/gae-dispatcher-emulator/...

また、Github Releasesにてバイナリの配布もしてますのでそちらもご利用いただけます。

Releases · karupanerura/gae-dispatcher-emulator · GitHub

macOSであればこういう感じでインストールできるでしょう:

$ curl -sfL -o ~/bin/gae-dispatcher-emulator https://github.com/karupanerura/gae-dispatcher-emulator/releases/download/v0.3.0/gae-dispatcher-emulator_darwin_amd64
$ chmod +x ~/bin/gae-dispatcher-emulator

実装

dispatch.yaml などを読めることを除けば素直なReverse Proxyとして動くと思います。

具体的には、X-Forwarded-For ヘッダを処理したりRFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1をもとにhop-by-hopなものとして定義されているヘッダフィールドを取り除くなどのことをしています。
このあたりはlib/Plack/App/Proxy.pm - metacpan.org の実装を参考にしました。

一応APIも公開していますのでforkして追いかけるのはつらそうだけど表面だけ変えたいとかあればお使いください(ただしインターフェースは突然変わるかもしれません):

godoc.org

なにか気になること、困ったこと、要望などあればお気軽にissueやTwitterなどでお知らせください。