表題の通り。
method="POST"
で送信した値がHTTP APIとしたAPI GatewayからLambdaにeventを渡す際、body
の中身がbase64 encodeされた文字列として渡される。
API GateWayから渡されるevent['body']は今の仕様だとbase64エンコードされて渡されるみたい。
— Fumiya Ichikawa (@LET__IT__RIDE) June 6, 2020
from urllib.parse import parse_qs
body = base64.b64decode( event['body'] )
param = parse_qs(body.decode('utf-8'))
でdictionaryに変換できる。
何故、base64になってるかは謎...
色々調べてみたんだけど、理由は謎。書籍やネット上の記事ではテキストとして扱ってるので、何か理由がありそうなんだけど...
API Gateway でのコンテンツタイプの変換 - Amazon API Gateway
ちなみに同様の事象に遭っている人もいる。
API GatewayのHTTP API、Base64エンコードされる条件 is 謎
— ./A.I (@zwihanderAI2) May 10, 2020
AWS Lambda実践ガイド。S3に配置したhtml からAPI Gateway叩いてlambda呼出してdynamoDBに書込み。サンプルコードだと動作せず、ひたすらトラブルシューティング(POSTしたbodyがbase64でした泣)何事もトラブルシューティングは勉強になるなぁ。関数内でprintすればCloudWatchLogsから中身見れるのね
— hayato matsushita (@hm90079007) April 27, 2020
API Gateway勝手にrequestをbase64に変換してくるのやめてくれ〜
— みょん (@myuon_myon) May 20, 2019
event['body']をbase64 decodeする
base64 decodeはbyte typeにdecodeされるので、byte -> strに変換してあげると扱いやすい。
from urllib.parse import parse_qs body = base64.b64decode( event['body'] ) param = parse_qs(body.decode('utf-8'))
その他、eventの変更点
僕の環境では、クライアントのリモートIPアドレスが
event['requestContext']['identity']['sourceIp']
ではなく、
event['requestContext']['http']['sourceIp']
で取れました(^_^;)