いままでのSPAのルーティング
AWSでReactなどのSPAを公開する場合、S3へアプリをデプロイしてCloudFrontからルーティングさせていました。
ただ一つ問題になるのが、index.html以外のリクエストにはS3が403のレスポンスを返却すること。そこで、CloudFrontのカスタムエラーレスポンスでindex.htmlのリクエストに書き換えて返却するという方法でこの問題を回避していました。
しかし、同一ドメイン内にSPAと通常のWebアプリケーションが同居している場合、この方法だと意図しないレスポンスを行いかねません。カスタムエラーレスポンスは、どのビヘイビアからのレスポンスであっても一律に処理してしまうという特性を持っています。
例えば、こんな感じにパスで切り分けられている場合、/article/1のページ内の処理で403を発行してしまうとCloudFrontで403が検知され、/spa/index.htmlへ飛ばされてしまいます。
http://example.com/spa/index.html
http://example.com/article/1
イケてない。
CloudFront Functionsを使ってルーティング
CloudFront Functionsに何をさせるのか?
リクエストがSPAの場合、URLをリライトして強制的に/index.htmlへ飛ばします。
CloudFront Functionsは、最大実行時間が1ミリ秒未満であることが強要されますがシンプルなリライト処理であれば問題なく実行できるはずです。
関数を作成
コンソール上から新規に関数を作成するとこんな感じになります。
これは、200レスポンスを強制的に返却するものですね。
functionの定義だけ残して関数の中身を変更します。
jsやcss、jsonなどをリクエストされた場合にそのまま処理を流すため、拡張子なしに限定してリライトをかけます。
もちろん、この条件を複雑にルーティングすることはできますが、処理時間の縛りが1msであることから、可能な限りシンプルにすべきでしょう。
関数を発行
CloudFront Functionsには開発ステージとライブステージがあり、関数を作成すると開発ステージにデプロイされます。
開発ステージではテストが行なえます。
ライブステージへデプロイするとロケーションエッジで関数が有効になります。
※おそらく、UIも機能も変わっていくと思うので特にキャプチャなどは載せない。
キャッシュビヘイビアへアタッチ
CloudFront Functionsは、ディストリビューションとイベントタイプ、キャッシュビヘイビアを選択してアタッチして終了です。
ディストリビューション | 作成したいずれかのディストリビューションを選択します。 |
イベントタイプ | ・ViewerRequest :リクエストで処理されます。 ・ViewerResponse :ビヘイビアからのレスポンスで処理されます。 |
キャッシュビヘイビア | ディストリビューションに設定してあるキャッシュビヘイビアのいずれかを選択します。 |
この、キャッシュビヘイビアを選択できるのがすばらしい。
何かというと、自分でリクエストのパスを選定しなくていいので、SPAのビヘイビアにだけアタッチすればその他のアプリケーションは気にする必要がないということ。
先にも書きましたが、カスタムエラーレスポンスではリクエスト先によらず、すべてのビヘイビアのレスポンスを処理してしまうことがネックでした。CloudFront Functionsではその問題が発生しません。もちろん、Functionsの処理自体もコンテンツだけを意識すればいいので簡素にかけます。
個人的に一番気に入ったところです。
まとめ
作るの簡単。
機能もシンプルなのでわかりやすい。
なにより、SPAのルーティング問題を解決してくれてハッピー。
参考↓