Lambda 側でも POST データを受け取れます。
application/x-www-form-urlencoded で送信されたPOSTデータを受信してみます。
import json
import urllib.parse
def lambda_handler(event, context):
# TODO implement
# イベントとコンテキストの内容を出力
print( "event:" , event )
print( "context:", context )
# QueryString をパースする
strBody = event.get('body')
param = urllib.parse.parse_qs(strBody)
# パラメータを取得する
strParam1 = param['param1']
strParam2 = param['param2']
# パラメータの内容を出力する
print( "strParam1:", strParam1 );
print( "strParam2:", strParam2 );
return {
'statusCode': 200,
'body': json.dumps('ok')
}
event.body に格納された文字列を urllib で parse する必要があります。
#!/bin/sh
TARGET='https://xxxx.execute-api.ap-northeast-1.amazonaws.com/default/lambda-test-04'
API_KEY="XXXX"
PARAM1="param1=aaa"
PARAM2="param2=bbb"
curl -o - "${TARGET}" -d ${PARAM1} -d ${PARAM2} --header "x-api-key:${API_KEY}"
実行結果として CloudWatch にパラメータが出力されます。
strParam1: ['aaa']
strParam2: ['bbb']
パースした結果は配列として格納されているようです。同じパラメータ名の変数がPOSTされた場合には配列で取れるようです。
では、multipart/form-data でファイルをPOSTすることができるかを確認しているのですが、ネットを検索するとできるようなことも書いてあるのですが、うまく設定できず未確認の状態です。
ただ、こちらでアップロードした方法は下記の方法で REST API にバイナリファイルを直接送りつけるということはできるようです。
下記の例は、lambda にPOSTした画像ファイル(test.jpg)をS3のtokyo20230412バケットに格納するサンプルです。
# -*- coding: utf-8 -*-
import json
import urllib.parse
import boto3
import base64
def lambda_handler(event, context):
# TODO implement
# イベントとコンテキストの内容を出力
print( "event:" , event )
print( "context:", context )
# パラメータを取得
param = json.loads( event['body'] )
file_data = param['file']
data = base64.b64decode( file_data.encode( 'utf8' ) )
client = boto3.client('s3')
client.put_object(Body=data,Bucket='tokyo20230412',Key='test.jpg')
return {
'statusCode': 200,
'body': json.dumps('ok')
}
上記のlambdaにPOSTをするPythonコードが下記のものになります。
このコードをローカルで実行するとAWS上のLambdaを経由してS3に画像ファイルが格納されます。
import json
import requests
import base64
image = "header.jpg"
data = open(image, 'rb').read()
encoded_data = base64.b64encode(data).decode('utf-8')
url = 'https://xxxx.execute-api.ap-northeast-1.amazonaws.com/default/lambda-test-05'
payload = {'file': encoded_data}
headers = {'x-api-key': 'XXXX'}
response = requests.post(url, data=json.dumps(payload), headers=headers)
print( response )
view を掌るブラウザ側からは JavaScript を使ってPOSTをすることになると思うので、multipart/form-data を使用できなくても、入力項目とファイルを個別のLambdaにPOSTすればよいだけなのですが、PHPで記述した既存のWebアプリケーションをServer less に移行する場合は改修が必要となるポイントとなります。