ぴよまるの雑多な技術所

生き悩んでいるエンジニアが興味のある分野を探すためにいろんなことに手を出します。AWSやコンピュータサイエンス自体、いろんな分野のコーディングの導入をします。今まではPythonとAWSでした。

Pythonで実装したLambda + API Gatewayで任意のエラーコードを返す

サーバレスな構成を作っている時、Lambdaのステータスコードを500で返してもAPI Gatewayで200に書き換わってしまうということがありました。その時は独自エラークラスを作って、マッピングテンプレートを設定してなどなど、大掛かりなことをしたのですが、マッピングテンプレートなしで任意のエラーコードを返す方法をまとめます。

全体図

LambdaがAPI本体、API GatewayAPIのエンドポイントになる構成です。

結論

先に結論を書くと、マッピングテンプレートは必要ありません。API GatewayのPOSTの「統合リクエスト」は「Lambda プロキシ統合の使用」のまま、Lambda側でエラー用のjsonをreturnすれば大丈夫です。

参考記事 https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html

以下に具体的なコードを載せます。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 プロキシ統合の使用」にチェックをするとよしなに行ってくれるため、マッピングテンプレートが不要です。

f:id:let_piyomaru:20200310105435p:plain
API Gatewayの設定
私の環境だと「POST」の方は「メソッドレスポンス」にステータスコードを登録する必要すらありませんでした。 留意点としては、Lambda側で返すjsonの項目がAWSによって定められています。その形さえ間違わなければ動くはずです。