はじめに
Lambdaと統合させたAPI Gatewayのエンドポイントを叩いたときに、JSONオブジェクトではなくJSON文字列が返ってくる事がありました。本記事ではその原因と対応方法についてまとめています。
結論
APIのエンドポイントを叩いてJSONオブジェクトを返り値として取得したい場合は、Lambdaのレスポンスはdict型のレスポンスを返すようにする。
環境
- API Gateway(GETメソッド)
- 統合タイプ:Lambda関数
- Lambda プロキシ統合:False
事象
APIのエンドポイントにGETリクエスト送った時に、本来だとJSONオブジェクトが返ってくる想定が、JSON文字列が返ってきました。
本来返ってくる想定のJSONオブジェクト
{"statusCode": 200, "body": {"message": "Hello, World!", "status": "success"}}
実際に返ってきたJSON文字列
{"statusCode": 200, "body": "{\"message\": \"Hello, World!\", \"status\": \"success\"}"}
原因
Lambda関数内でjson.dumps()を使用し、レスポンスボディを文字列化していたことでした。
import json
def lambda_handler(event, context):
response = {
"message": "Hello, World!",
"status": "success"
}
return {
'statusCode': 200,
'body': json.dumps(response) # このdumpsが不要
}
解決策
json.dumpsは不要でした。dumpsのラップを削除し、Lambdaのレスポンスとしてdict型の変数 response
を返すようにしました。
import json
def lambda_handler(event, context):
response = {
"message": "Hello, World!",
"status": "success"
}
return {
'statusCode': 200,
'body': response # 文字列化せずにそのまま返す
}
API Gatewayのエンドポイントを叩くと、想定通りのレスポンスが返ってきました。
{"statusCode": 200, "body": {"message": "Hello, World!", "status": "success"}}