Hoxyでアセットプロキシサーバを立てる
August 6, 2016
webフロント開発で辛いことといえば、ローカルに開発環境を整えることです。
と言っても、jsのビルドがー、とかsassのビルドがー、とかそういった類の話ではありません。 そんなものはgulpなりwebpackなりでいくらでも解決できます。
何が辛いって、良い感じのAPIレスポンスを返してくれるAPIサーバを立てることです。
rails & MySQLがあれば動くようなシンプルな構成であれば問題にはなりません。 しかし、裏側で各種Cloud Serviceを使っている場合はそもそもローカルに同じ環境を用意すること自体が困難です。
また、データを更新するのに非同期ワーカーが必要だとすると、非同期ワーカーの動作環境も作らなければいけません。
ただAPIレスポンスが返って来れば良いだけなのに。。。
だがちょっと待ってください。
ローカルにそもそも全て用意する必要はあるでしょうか?
一通り動作するサーバサイドの環境はstaging環境に用意されています。 (そういう現場でなかった場合はこの記事を読む必要はありません。) 各種Cloud Serviceもstaging用に用意され、非同期処理のためのワーカーも動いています。 良い感じのデータが返ってくるテストアカウントもあります。
自分がやりたいことは、js/cssの実装です。 gulpでビルドする環境も整っています。
staging環境のサーバサイドを利用しつつ、js/cssだけはローカルのビルド結果に差し替えてしまえば良くないですか?
Hoxy
Hoxyというnode.js製のproxyサーバを使ってやってみましょう。
証明書の準備
APIエンドポイントがhttpsの場合、proxyサーバからリクエストの中身を見ることはできません。 しかし、特定リソースの取得先をローカルに向けるには、中身を見る必要があります。
proxyサーバ自体を自己証明によるhttpsサーバにすることで解決できます。 詳しいことはこちらで説明されています。
http://greim.github.io/hoxy/#direct-https-proxying
要するに、httpsの通信を一旦proxyで平文に戻し、proxyから出るときに再びまた暗号文にしているのです。
証明書の作り方などは、http://greim.github.io/hoxy/#intercept-https を参考にしてください。
証明書を作ったら、信頼する証明書としてインストールしておきましょう。 インストールしないとブラウザで警告がでます。 またHSTSが有効だと、信頼できない証明書を例外扱いにすることもできません。 (chromeでそうだった)
サーバの立ち上げ
gulpの場合は以下のタスクを定義します。
各種パス、ドメイン名などは適宜変えてください。 ここでは /assets/bundle-digest.js をローカルのファイルに差し替えるとします。
gulp.task('proxy', () => {
const proxy = hoxy.createServer({
certAuthority: {
key: fs.readFileSync('/path/to/秘密鍵'),
cert: fs.readFileSync('/path/to/自己証明書'),
},
}).listen(8888);
proxy.intercept({
phase: 'request',
hostname: 'staging環境のドメイン',
}, (req, resp, cycle) => {
if(req.url.match(/bundle.*js/)) {
cycle.serve('/path/to/ローカルでビルドしたファイル');
}
});
});
ローカルのrailsサーバ等から動的に生成したリソースを返す場合は、intercept
のコールバック内を以下のようにします。
railsサーバがlocalhost:3000で動いているとすると、
(req) => {
req.fullUrl('http://localhost:3000/assets/bundle.js');
}
となります。
gulp proxy
でlocalhost:8888
にプロキシサーバが立ち上がります。ブラウザのプロキシに設定しましょう。
http/httpsの両方に設定してください。
https://staging環境のドメイン/ にアクセスしてみましょう。 scriptタグのsrcに指定された /assets/bundle-12345.js へのリクエストが実行されますが、中身はローカルのリソースに置き換わっています。