SPA な開発をしていると、RESTful API 用の Proxy が欲しくなります。でも、そのために Apache 入れたり nginx 入れるのはちょっと違うよなと思っていて、Brunch 使っている人向けの情報です。
Brunch でローカルサーバーをカスタマイズ
brunch-config.coffee でサーバーを指定すればよろしい。
exports.config =
# See http://brunch.io/#documentation for docs.
files:
javascripts:
joinTo:
'javascripts/app.js': /^app/
'javascripts/vendor.js': /^(?!app)/
stylesheets:
joinTo: 'stylesheets/app.css'
templates:
joinTo: 'javascripts/app.js'
server:
path: 'local-server.coffee'
run: yes
ローカルサーバーを書く
いろいろあると思いますが、オーソドックスに Express を使います。http proxy 用に request も使います。
express = require 'express'
sysPath = require 'path'
http = require 'http'
request = require 'request'
exports.startServer = (port, path, callback) ->
app = express()
app.use express.static path
proxy = 'http://192.168.80.96:8080'
api_endpoint = 'http://192.168.80.150:8002'
request = request.defaults
proxy: proxy
app.all '/api/*', (req, res) ->
req.pipe(request(api_endpoint + req.url)).pipe(res)
# rewrite other resource to index.html
app.all '/*', (req, res) ->
res.sendFile sysPath.resolve sysPath.join path, 'index.html'
server = http.createServer app
server.listen parseInt(port, 10), callback
server
実装は単純で、/api 宛てのリクエストを絶対 URL にして、request に pipe して結果を res に pipe。抽象度高すぎてしびれます。それ以外の URL については index.html を返すようにしてリロード対策。
この例では内部 proxy 指定してますけど、API サーバーに直接アクセス可能なら、いらない設定です。あとは、google maps など外部の API を呼ぶときに corporate proxy 経由しないとダメーなときに指定したりします。
はまりどころ
当初、proxy 用に http-proxy を使ってたんですが、内部 proxy を経由するとどうにもうまく動きませんでした。原因究明に疲れ果てた頃に request に出会い、試しに使ってみると拍子抜けするくらいあっさり成功。。。
下手に利用実績のあるプロダクトだと、なんとか動かそうと執着して時間を無駄にしてしまうことがあり、良くない傾向だなと反省しました。