[AWS]APIGateway上でExpressのpublicルーティングを通したかった


はじめに

新卒ゆるゆるアドベントカレンダー21日担当です!
最近AWSを触らせてもらう機会があり、それについて少々。

背景

「あんまアクセスないサイトだし、ServerlessでWebサービス作れたら低コストな運用が出来るのでは!?」っていう流れで、AWS,Lambdaで動くWebサーバの構築をNode.js&Expressを使って行いました。
Expressのスケルトンコードを用意し、普段のようにpublic配下にクライアントJSやCSSのリソースを入れ込んで、下記のexample.htmlように自身のURLを指定してリソースを読み込んでいました。
ですが、Serverless.ymlで特定のルーティングをLambdaFunctionに紐づけて定義してしまっているため、example.htmlのようなリソースURLをリクエストされても対応するLambdaFunctionが無いと怒られるだけでした。(この問題の解明に3日ほど費やしました)

sample.html
<head>
<link rel="stylesheet" type="text/css" href="/public/css/example.css">
</head>

(以前書いた記事でExpressスケルトンコードでのサーバ構築手法も書いてるのでぜひご覧ください)

対応方法の検討

クライアントからのリソースのリクエストは「/public/」で始まる事から、以下の三つを検討しました。

  1. /public/でアクセスできるLambdaFunctionを定義し、そこで実際の/public/フォルダから検索して返す
  2. /public/でアクセスできるLambdaFunctionを定義し、そこでS3バケットから指定されたリソースを引っ張ってきて返す
  3. CloudFrontを使い、/public/で来たリクエストをAPIGatewayではなく直接S3バケットに向ける

純粋なAPIGatewayとLambdaの動作、Expressの動作を保証しつつ、可用性を求めた結果3を選択しました。CloundFrontはcdnとして元々導入予定且つS3の運用コストの低さからこの選択は最善であると判断しました。

対応

AWSConsole上からCloudFrontの設定をしていきます。
新しいDistributionを作り、OriginにはAPIGatewayのARNを、CustumOriginにはS3のARNを設定します。Originの設定例を図1に、Behhavioursの設定例を図2に示します。

図1(Originの設定例)

図2(Behaviorsの設定例)

おわりに

アドベントカレンダーのタイトルにそぐわない内容だったかもしれませんが、もしServerlessでWebサーバを作る人の参考になれば幸いです。
実際にはAWSConsoleから直接Distributionをいじるのではなく、Terraformを使ってドキュメント化を行っております。いずれそれを記事にすると思います。
更にs3へのリソースデプロイもshellで自動化したので、それもいつか記事にするかもしれません。
ご興味がある方は是非ご覧になってください。
最後まで読んでいただきありがとうございました。