書いてる事
Next.jsで一部のリクエストを別環境へproxyしたいケースは多いかと思います。
例えば、下記のようなケース
- フロントエンドをバックエンドと環境を分離している
- Backend向けAPIだけ裏側へproxyしたい
- バックエンド環境を自身の開発環境に用意するのが面倒(管理・運用面で)
- できれば、最新状態がキープされている共通環境側へproxyしたい
上記の場合の対応方法について書きました。
書いてない事
Node(JavaScript)以外で頑張る方法。
Nodeがあれば再現できる方法がフロントエンド開発者としては嬉しいと思うので。
1. micro-proxyをNextと別で立ち上げる
あまりオススメしない方法。
zeitが出しているNodeライブラリーであるmicro-proxyを使う案。別プロセスでproxy立ち上げ、一部のリクエストをproxy向けにリクエストを飛ばしてproxyさせる手法。ただし、この方法は問題点が何個かあって
- そもそもarchiveされているライブラリー
- micro-proxyはNextと別プロセスで立ち上げるので別ポートでListenする必要があり、Nextとポートを分けないといけない
- リクエストするクライアント側からも振り分けないといけなくなる
- __proxyするリクエスト__と__proxyしないリクエスト__でクロスドメインになるのでその対処が必要
- 例えば、Nextは
localhost:3000
、micro-proxyがlocalhost:9000
だと、micro-proxy向けのリクエストはクロスドメイン扱いとなり、。ブラウザ側で拒否される
- 例えば、Nextは
2. NextのCustome Server(Routes)上でhttp-proxy-middlewareを使う。
個人的なオススメ。
http-proxy-middlewareはNode製のproxy library。Nodeのweb framework、例えばexpressなどで簡単に利用できる。これをNextのCustom Server上で利用する。
以下は実際に設定したコード例です。NextのCustom Server例を参考にしました。
const express = require('express')
const next = require('next')
const proxy = require('http-proxy-middleware')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.use(
'/api',
proxy({
target: 'http://www.example.org',
changeOrigin: true
})
);
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
上記でCustom Serverを起動すると/api
向けのリクエストはhttp://www.example.org
へproxyされ、他リクエストはNext.js内部で処理(SSRなど)する。同プロセス、同ポートへのリクエストとなり、クロスオリジンの問題は起きない。
まとめ
2番目がオススメ。ただ、他にオススメがあれば教えてください。