
API Gateway と Lambdaを使ってサーバレスでいい感じのリダイレクト環境を作る
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、岩本です。
さて、サイトリニューアルやシステムのリプレイスなどで、サイトのドメインやURL構成が変わる場合、
既存ドメイン・URLへのアクセスを、新環境へリダイレクトするケースが発生するかと思います。
そこで、リダイレクト用だけに維持し続けるのは勿体無いので、API Gateway と Lambda を使って
リダイレクト用の環境を構築して見ました。
やりたいこと
- URL: https://old.hogehoge.com/user?name=xxxxx
に接続が来たら
- URL: https://new.hogehoge.com/user/name/xxxxx
へと、リダイレクトを行いたい。
概要
- APIGatewayで受け取ったURL Query Stringの値をLambdaに引き渡す
- Lambdaでいい感じに変換
- Lambdaで変換された出力を元に、APIGatewayで レスポンスコード(301)の出力と、Locationヘッダーに結果を付与する
Lambdaの用意
まず、URLの変換を行うためのLambdaを用意します。
仕組みは、入力された値をリダイレクト先のURLに付与して、Locationの値として出力します。
def lambda_handler (event, context):
name = event['name']
header_location = ("https://new.hogehoge.com/user/name/%s" % name)
result = {"Location": header_location}
return result
Lambdaのテスト
まずは、Lambdaが期待値通りの動きをすか確認するため、入力値は以下のように設定しテストを行いました。
- 入力
{
"name": "hogehogetarou"
}
結果、出力は以下のようになっているので、成功です。
- 出力
{
"Location": "https://new.hogehoge.com/user/name/hogehogetarou"
}
APIGatewayの用意
次に、API Gateway にてAPIを作成します。
- リソースを作成
- メソッドを作成
- 今回は、ANYとして作成しました。
- ANYメソッドからLambdaが呼び出されるように設定
- 作成された
ANYメソッドにて以下を設定
Method Request
Method RequestよりURL Query String Parameters に name としてパラメータの追加をします。
追加するパラメータは以下の通りです。
{
"name": "$input.params('name')"
}
次に、パラメータを入力後Cachingにチエックをします。
Integration Request
Integration RequestよりBody Mapping Templatesに
application/jsonのContent-Typeを追加します。
追加後application/jsonの内容を以下の通りとします。
{
"name": "$input.params('name')"
}
ここまでが、URLへのアクセスに基づくLambdaへの値の入力設定となります。
Method Response
次にLambdaで生成されたURLをヘッダーに含めるための設定をします。
Method Responseにて、HTTP Statusにリダイレクトのレスポンスコードとなる301を追加します。
次にResponse Headers for 301にて、Header にLocationを追加します。
integration response
最後に、integration responseにて301を追加し200を消します。
追加した301のHeader MappingsにMethod Responseにて追加されたLocationがあるので、
値にintegration.response.body.Locationを追加します。
以上で完了です。
TEST
最後にテストをします。
TESTに進みQuery Stringsにnameという項目があるのでhogetarouなど適当な値を入れテストを実行します。
結果がこちらです。
Request: /?name=hoge Status: 301 Latency: 111 ms Response Body
- Response Body
{
"Location": "https://new.hogehoge.com/user/name/hogetarou"
}
- Response Headers
{"X-Amzn-Trace-Id":"Root=1-58ca0c80-b6fe8fb2f9708f96da189497","Content-Type":"application/json","Location":"https://new.hogehoge.com/user/name/hogetarou"}
- リクエストに対し、302のエラーコードが帰っています。
- ヘッダーの
Locationにきちんと生成されたURLが入っています。
ここまでできれば、今作成したResourcesを元にAPIを作成することで、完了です。
解説
入力
Method RequestのURL Query String Parametersとintegration responseのBody Mapping Templatesに設定した、
"name": "$input.params('name')"
により、URLのQuery Stringの値がLambdaに引き渡されます。
出力
引き渡された値は、integration responseのHeader Mappings Method Response に設定した
integration.response.body.xxxにて、ヘッダーに値が割り当てられます。
今回はLambdaでの出力値Locationつまりintegration.response.body.Locationと設定しました。
今日のわさび様<
お饅頭感がすごい。窓ガラス掃除しないとなぁ。








