HTTP リダイレクション管理
概要
リダイレクト管理はウェブサイトでは一般的な要件であり、存在しないURLのリダイレクト(期限切れのキャンペーンやWebサイトの構造変更後など)や、国に基づいてコンテンツをローカライズするためによく使用されます。リダイレクトはオリジンまたはCDNで管理できます。CDN レベルでリダイレクトを管理することで、オリジンの負荷を軽減し、応答時間を短縮できます。静的ホスティング (S3 など) のように、リダイレクトをオリジンで管理できない場合があります。CloudFront のリダイレクトは、そのエッジ機能を使用して管理されます。
アーキテクチャ上の決定
リダイレクトは、要件に応じて、エッジ機能を使用してさまざまな方法で実装できます。ビジネスに最適な実装を設計するには、次の質問を検討してください。
- リダイレクションロジックはどのくらいの頻度で更新しますか? さまざまなチームが並行してリダイレクトを頻繁に使用する場合、単純で時折行われるA/Bテストと比較して、より高度な実装が必要です。
- ロジックにはいくつのリダイレクションルールがありますか? リダイレクションデータベースのサイズは、さまざまなストレージオプションを評価する際に考慮すべき要素です。
- リダイレクトは静的ですか、それとも動的ですか(ユーザーの国やデバイスの機能によって異なるなど)? リダイレクションロジックが動的な場合は、応答を変化させるために必要なパラメータがすべて揃っているコンテキストで実行する必要があります。
- URL をユーザーに対して透過的に書き換えるのか、それとも 3xx リダイレクションを送信するのか。
CloudFront のエッジ機能を使用したリダイレクトの実装について学ぶには、このハンズオン形式のワークショップを検討してください。次のセクションでは、CloudFront を使用したリダイレクション管理の一般的な実装を 2 つ紹介します。
一般的ユースケース
静的 HTTP リダイレクト
ほとんど変更されないわずかなルールがある HTTP リダイレクトを実装する場合は、関数コードにリダイレクトロジックが埋め込まれたビューワーのリクエストイベントで、CloudFront Function を設定します。リダイレクトロジックが進化したら、関数コードを更新できます。新しいロジックは数秒以内にユーザーに適用されます。
たとえば、ビューワーのリクエストイベントで設定された次の CloudFront 関数は、選択した国 (スペインと UAE) のユーザーに 3xx HTTP レスポンスを送信して、ローカルバージョンのシングルページアプリケーション (https://example.com/ -> https://example.com/es/ など) にリダイレクトします。これを機能させるには、オリジンリクエストポリシーに cloudfront-viewer-country ヘッダーを含める必要があります。このヘッダーを、関数ロジックで使用される CloudFront 関数イベントオブジェクトで使用できるようにするよう CloudFront に指示します。このサンプルコードでは、ユーザーが別の国バージョンの SPA を要求しない限り、ユーザーは自分の国に基づいてリダイレクトされることに注意してください。
function handler(event) {
var request = event.request;
var headers = request.headers;
var host = request.headers.host.value;
var supported_countries = ['ie','ae', 'es']; // countries in which you'd like to serve a localized version of your Single Page Application
var defaultCountryIndex = 0; // default country index in the support_countries array. here it is 'ie'
if ((supported_countries.includes(request.uri.substring(1,3))) && ((request.uri.substring(3,4) === '/') || (request.uri.length === 3))) {
// If one of the supported country codes is included in the path (e.g. /es/about) then add index.html when needed to the reauest
return requestWithIndexHTML(request);
} else if ((headers['cloudfront-viewer-country']) && (headers['cloudfront-viewer-country'].value.toLowerCase() !== supported_countries[defaultCountryIndex])){
// Otherwise if the user reauest is coming from one of the supported countries except the default one, then redirect to country specific version (e.g. /about -> /es/about)
var response = {
statusCode: 302,
statusDescription: 'Found',
headers: { location: { value: `https://${host}/${headers['cloudfront-viewer-country'].value.toLowerCase()}${request.uri}` } },
};
return response;
} else {
// Otherwise send rewrite the request to the default country path, add index.html if needed and return
request.uri = '/'+supported_countries[defaultCountryIndex] + request.uri;
return requestWithIndexHTML(request);
}
}
// Add index.html to SPA path when needed
function requestWithIndexHTML(request) {
if (request.uri.endsWith('/')) {
request.uri += 'index.html';
} else if (!request.uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
一括 HTTP リダイレクト
CloudFront Function では、CloudFront KeyValueStore を使用することで、最大関数サイズの 10 KB に収まる範囲を超える大規模なリダイレクトマッピングをサポートすることもできます。例えば、一致させたい URI をキーに格納し、リダイレクト URL を値に格納できます。 ビューワーのリクエストのイベントオブジェクトで使用できる URI は、一致する URI かどうかを評価できます。キーに URI が存在する場合、関数は関連付けられた値を含む 3xx リダイレクトを返すことができます。
KeyValueStore を使用すると、定期的に変化するデータをコードから切り離すという利点もあります。KeyValueStore は、グローバル (すべての PoP)、低レイテンシーの読み取り、大規模なキーバリューデータストア (1 秒あたり数百万リクエスト) として理想的です。
HTTP リダイレクトの高度な要件
Lambda@Edge ベースのソリューションは、KeyValueStore の最大サイズ (5 MB) では十分ではない高度なリダイレクト要件や、1 秒間に数回の API コールという速度の制限を変更できない場合により適しています。シナリオの例としては、さまざまなマーケティングチームが毎日何十万ものキャンペーンのリダイレクトを更新する場合などがあります。
このアーキテクチャでは、オリジンリクエストイベントに設定された Lambda@Edge 関数がキャッシュミスのたびに実行され、どのリダイレクションルールを適用するかを S3 や DynamoDB などの外部ルールストレージで確認します。ルールは選択したストレージで直接管理され、その上にシンプルなUIを構築して管理を容易にすることができます。このブログでは、S3 ベースのストレージと認証された管理 UI を使用したこのアーキテクチャの例について説明します。