やりたかったこと
S3へアップロードされるXMLファイルをAPI Gatewayを介して返却する。
やったこと
- 前提として、S3とLambdaの連携(オブジェクトの取得)と LambdaとAPI Gatewayの連携(Lambdaから返る値をAPI Gateway経由で返す)が できていること。
まずはLambdaのコード
from __future__ import print_function
import urllib
import boto3
s3 = boto3.client('s3')
def lambda_handler(event, context):
# get object
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
try:
response = s3.get_object(Bucket=bucket, Key=key)
content = response['Body'].read(response['ContentLength'])
return {"body": unicode(content, 'utf-8')}
except UnicodeDecodeError as de:
print(de)
return json.loads(err_decode_msg)
こんな感じのコードで LambdaからS3にアップロードされているファイルの中身を 取得(content)して、JSONで返却する。
API Gatewayの設定
・メソッドレスポンス レスポンスモデルにコンテントタイプ: text/xml, モデル: Empty追加 ・統合レスポンス 本文マッピングテンプレートのContent-Typeにtext/xml追加 テンプレートに下記追加
#set($inputRoot = $input.path('$'))
$inputRoot.body
これで念願のXMLを返すことができました。
まとめ
できないこと
・APIキー以外のアクセス制限 →使うコンポーネントを増やせばできます。 例えば、CloudFrontを用意してWAFで制限をかけてやることもできますが お値段がお高いです。 だったら、EC2でという気持ちになります。 私は、アプリ内に接続元IPアドレス確認関数を定義しました。 アクセス制限にはなっていないですね。機能が使えるかどうかのレベルなので。
・HTTPでリクエストを受ける CloudFrontを使ってください。
いいなあと思ったこと
・API GatewayからLambdaに渡すテンプレートを指定できる。 ・LambdaからのレスポンスをJSONから変更できる。 今回のようなXMLへとかHTMLへとか
福山
最近技術触れてないかも