🧚
Next.js でProxyAPIを実装する
これは何?
Next.jsのAPI機能を使ってProxy機能を作成します。
/api/proxy/
配下で外部APIへプロキシリクエストできるため、CORSを回避できたり、next/Image componentで利用する画像をAmazon S3等外部リソースへプロキシすることができます。
ディレクトリ構成
pages/api
└── proxy
└── [...slug].ts
Next.jsではpages/api以下をAPIサーバとして利用することができます。
特定パス以降を全てプロキシするため、ファイル名を[...slug]
とします。
proxy実装
http-proxyを使って実装します。
import { IncomingMessage, ServerResponse } from 'http'
import httpProxy from 'http-proxy';
const target = "https://api.exchangeratesapi.io/"
const proxy = httpProxy.createProxyServer({ target, changeOrigin: true });
export default async function handler(req: IncomingMessage, res: ServerResponse) {
req.url = req.url!.replace(new RegExp("^/api/proxy"), "")
return new Promise((resolve, reject) => {
try {
proxy.web(req, res, { proxyTimeout: 5000 }, (e) => {
reject(e)
})
resolve
} catch (e) {
reject(e)
}
})
}
サンプルとして通貨取得APIを利用しました。
handlerは非常にシンプルでproxyへreq, resを渡しているだけです。
http-proxy
にpathRewrite
といったPathを書き換えるオプションが提供されていないようだったのでreq.urlを自前で書き換えています。
出力
Nextを起動し取得が確認しましょう。
$ curl "http://localhost:3000/api/proxy/latest?base=JPY"
{"rates":{"CAD":0.0123500747,"HKD":0.0747017213,"ISK":1.2284838481,"PHP":0.4629647096,"DKK":0.0584626267,"HUF":2.8651261495,"CZK":0.206727973,"GBP":0.0071416333,"RON":0.0383219367,"SEK":0.0792580366,"IDR":136.0182346931,"INR":0.7069244675,"BRL":0.0500801698,"RUB":0.7088603317,"HRK":0.0592996935,"JPY":1.0,"THB":0.2894443134,"CHF":0.0085372947,"EUR":0.0078597815,"MYR":0.039027745,"BGN":0.0153721607,"TRY":0.0708771516,"CNY":0.0629332705,"NOK":0.0829206948,"NZD":0.0134960308,"ZAR":0.1412017606,"USD":0.0096353061,"MXN":0.1917794545,"SGD":0.0127910084,"AUD":0.0126707538,"ILS":0.0309384579,"KRW":10.5347009353,"PLN":0.035611098},"base":"JPY","date":"2020-12-29"}
Discussion