Pythonで実装したLambda + API Gatewayで任意のエラーコードを返す
サーバレスな構成を作っている時、Lambdaのステータスコードを500で返してもAPI Gatewayで200に書き換わってしまうということがありました。その時は独自エラークラスを作って、マッピングテンプレートを設定してなどなど、大掛かりなことをしたのですが、マッピングテンプレートなしで任意のエラーコードを返す方法をまとめます。
全体図
LambdaがAPI本体、API GatewayがAPIのエンドポイントになる構成です。
結論
先に結論を書くと、マッピングテンプレートは必要ありません。API GatewayのPOSTの「統合リクエスト」は「Lambda プロキシ統合の使用」のまま、Lambda側でエラー用のjsonをreturnすれば大丈夫です。
以下に具体的なコードを載せます。POSTで{'test': '何か文字列'}という値を送信するという想定です。
Lambda
import json def lambda_handler(event, context): body = json.loads(event['body'])#例えばbodyを読み込んで if (len(body['test'])>10000):#文字が長すぎたら500エラーを返す return { 'errorType': "InternalServerError", 'httpStatus': 500, } #文字が長すぎなければ200のレスポンス return { 'statusCode': 200, 'isBase64Encoded': False, 'body': json.dumps({'result': 'OK!'}) , 'headers': { "Content-Type" : "application/json", "Access-Control-Allow-Origin" : "*" } }
API Gateway
これから記事を書く予定の記事のserverless.yamlの設定をコピペすれば動きます。書いたらリンクをはります。 おそらく「OPTIONS」と「POST」の2つのリソースができていると思いますが、「OPTIONS」はpreflightレスポンスに使います。「POST」の方が実際にLambdaにリクエストを送るリソースで、細かいマッピングは「統合リクエスト」の中の「Lambda プロキシ統合の使用」にチェックをするとよしなに行ってくれるため、マッピングテンプレートが不要です。 私の環境だと「POST」の方は「メソッドレスポンス」にステータスコードを登録する必要すらありませんでした。 留意点としては、Lambda側で返すjsonの項目がAWSによって定められています。その形さえ間違わなければ動くはずです。