Cloudflareにおけるパスベースのルーティング
/api/*
というパスにマッチする場合だけAPIサーバーにリクエストが飛ぶようにしたいという要求はよく発生するものだと思いますが、こういった処理をCloudflareで実現する方法について説明します。
CloudflareにはPage Rulesという機能があり、パスベースでリクエストに対してさまざまな制御ができます。とても便利ですが、オリジンをパスベースで変えるにはEnterpriseプランが必要となります。Enterpriseプランの価格は要見積もりなので定かではありませんが、非常に高額になることは想像できます。
そこで、Cloudflare Workersを使ってパスベースでオリジンを切り替えます。
この方法であれば、無料プランから要求を実現することができます。
設定方法
Cloudflare Workersでは、URLパターンとWorkerの組み合わせを指定します。URLパターンにマッチするリクエストが来るとWorkerが起動してリクエストに対して処理することができます。
https://example.com/api/*
を https://api.example.com/api/*
にリクエストをルーティングする例です。
- Workerを作成する。
Workersの管理ページから「Workerを作成」ボタンを押すとエディターが起動するので、コードを入力します。handleRequest()の内容を見てもらうと非常にシンプルにリクエストを書き換えられるのが分かります。
addEventListener('fetch', function(event) {
const { request } = event
const response = handleRequest(request).catch(handleError)
event.respondWith(response)
})
async function handleRequest(request) {
const { url } = request
const { pathname } = new URL(url)
if (pathname.indexOf('/api/') === 0) {
const newUrl = `https://api.example.com${pathname}`;
const newRequest = new Request(newUrl, {
body: request.body,
headers: request.headers,
method: request.method,
redirect: request.redirect
})
return fetch(newRequest);
}
return new Response('Not Found', { status: 404 })
}
function handleError(error) {
console.error('Uncaught error:', error)
const { stack } = error
return new Response(stack || error, {
status: 500,
headers: {
'Content-Type': 'text/plain;charset=UTF-8'
}
})
}
2. URLパターンとWorkerを登録
Workersのページからルートを追加します。作成したWorkerの名前がmy-routingとした場合、下記のように入力して保存します。
これで完了です。 https://example.com/api/abc
のリクエストは https://api.example.com/api/abc
にプロキシされます。
どこまで無料か
無料プランではWorkersには 100,000 requests/day の制限があります。
秒間1リクエスト強くらいなので、アクセスのあるサイトではすぐに制限を超えるかもしれませんが、有料プランも$5からで非常に安く使えます。