HTTP APIや関数URLでもPOSTデータを受け取りたい
手軽に実装できてお財布にも優しいHTTP APIですが、POSTデータを受け取るのに一手間必要です。
リクエストbodyはbase64エンコードされた状態で取得できるため、 デコード & jsonパースしてあげる関数を使えばOKです。
コード
Node.js
getBodyOnLambda.js
function getBodyOnLambda(event_body) {
let body_string_utf8 = Buffer.from(event_body, 'base64').toString('utf-8');
//日本語が含まれる場合はdecodeURIする
//decodeURIComponentでは無くdecodeURIなのは、POSTされたデータの中に&が含まれているとJSON変換時にうまくいかないため
body_string_utf8 = decodeURI(body_string_utf8);
//パラメーター形式文字列のJSONへの変換
const post_data = {};
body_string_utf8.split(/\&/g).forEach(item => {
//特殊文字もデコードして、keyとvalueに分ける
const [key, value] = decodeURIComponent(item).split(/\=/);
//JSON文字列の場合はJSONに変換して
try{
post_data[key] = JSON.parse(value);
} catch(e) {
post_data[key] = value;
}
});
return post_data;
}
// example
// request body: { mail: hogehuga@example.com }
exports.handler = async (event, context, callback) => {
const body = getBodyOnLambda(event.body);
console.log(body.mail); // hogehuga@example.com
context.done(null, body.mail);
};
Python
get_body_on_lambda.py
import base64
import urllib.parse
import json
def get_body_on_lambda(event_body):
body_query = base64.b64decode(event_body).decode()
body_dict = urllib.parse.parse_qs(body_query)
# valueが配列に入っているので出す
for key in body_dict:
body_dict[key] = body_dict[key][0]
return body_dict
# example
# request body: { mail: hogehuga@example.com }
def lambda_handler(event, context):
body = decode_body(event['body'])
print(body['mail']) # hogehuga@example.com
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps(body)
}