背景
API Gateway + Lambda(Python) の REST API があったのですが、えいやで作ったのでエラーハンドリングを全然していませんでした。
全てステータスコード200で返してパラメータでエラーかどうかを設定する方法のが簡単そうでしたが、やっぱり個人的に気持ち悪さを感じるのできっちりステータスコードを使い分けようと思いました。
AWS初心者の私には結構複雑だったのでメモっておきます。
自分的ベストプラクティスのつもりですが、一般的なベストプラクティスがあればぜひコメントください。
結論
先にざっくりと結論から。
API Gateway の設定
Lambda でやること
模索している時は大変だったけど結論にするとなんと簡単そうなことか・・・
API Gateway の設定
メソッドレスポンスにステータスコードを追加する
- メソッドを選んでメソッドレスポンスを選択
- [レスポンスの追加]から追加したいステータスコードを入力して追加
これだけです。簡単です。
今回は400を追加しています。(200はデフォルト)
総合レスポンスにステータスコードに対応するマッピングを追加する
- メソッドを選んで総合スポンスを選択
- [統合レスポンスの追加]からステータスコードに対応するマッピングを設定する
項目 | 値 |
---|---|
Lambda エラーの正規表現 | ^\[400\].* |
マッピングテンプレート Content-Type |
application/json |
マッピングテンプレート JSON内容 |
{ "errorMessage": "$input.path('$.errorMessage')" } |
正規表現は"[400]"で始まるerrorMessageにマッチします。
マッチングテンプレートはレスポンスに"errorMessage"だけ設定されるようにしています。
そのままだとスタックトレースとかも出てしまうので。
この辺はお好みで設定してください。
このように設定を入れると
{
"errorMessage": "[400] バリデーションエラー",
"errorType": "Exception",
"requestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"stackTrace":[
"hogehoge"
]
}
というLambdaのレスポンスを検知するとステータスコードが400になり、
{
"errorMessage": "[400] バリデーションエラー"
}
に変換して返却してくれます。
設定を入れたらAPIのデプロイをして反映させます。
Lambda でやること
マッピングに該当する"errorMessage"を返却する
raise Exception('[400] バリデーションエラー')
このように例外を発生させてあげるだけで必要としている以下のようなレスポンスが生成されます。(上で書いた奴と同じレスポンス)
{
"errorMessage": "[400] バリデーションエラー",
"errorType": "Exception",
"requestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"stackTrace":[
"hogehoge"
]
}
結果
これが私のやりたかった形でした。
あとはLambda側で独自の例外を作ったりをすればいい感じになるかなと思います。