1. 背景:
S3にアップロードするWebを作成する
2. 構成:
① クライアントからAPIGatewayにアクセスする
② Lambda機能をコールする
③ クライアントがアップロードするファイルをS3に書き込む
3. 処理概要:
- クライアントからファイル名存在しているかをチェックするリクエストを送る
- サーバーはpresigned_urlを作成し返却する
- 貰ったpresigned_urlによりファイルをアップロード実行する
4. 作成手順:
Step1: HTMLFrontEndを作成
Step2: Lambda変数を作成
① 変数名
② Lambda書く言語を選択
③ 選択するロールの権限でLambda作成
Step3: Lambdaコード書く
① GETステートメントであればユーザーから送るファイル名が存在しているかをチェックする
if event['httpMethod'] == 'GET':
#1 ユーザーから送ったファイル名を取得し処理する
fileName = event['queryStringParameters']['fileNameOfCSV']
# どのフォルダーをチェック対象にする変数
bucket = "XXX"
prefix = "YYY/"
try :
s3Objects = s3.list_objects(Bucket=bucket, Prefix=prefix)
if 'Contents' in s3Objects:
keys = [content['Key'] for content in s3Objects['Contents']]
keys.remove(prefix)
for i in range(0, len(keys)):
if keys[i] == (prefix + fileName) :
booCheckFileNameIsValid = False
break
else:
booCheckFileNameIsValid = False
except:
booCheckFileNameIsValid = False
② POSTステートメントであればpresigned_urlを作成し返却する
elif event['httpMethod'] == 'POST':
print("POST")
#メイン
csvFromUser = event['body']
#1 S3に保存する
bucket = 'XXX'
data = json.loads(csvFromUser)
upload_key = 'YYY/' + data['fileNameOfCSV']
# Generate the presigned URL for put requests
presigned_url = s3.generate_presigned_url(
ClientMethod='put_object',
Params={
'Bucket': 'XXX',
'Key': upload_key,
'ContentType': 'text/csv',
}
)
Step4: APIGateway作成
① トリガーを追加
② リソース(とメゾンド)を作成
③ ステージを作成
作成したらURLを取得しFrontEndでAPIコール処理にて利用する
5. CORS問題:
実行してみればGETステートメントでCORS問題が発生する
原因:APIGatewayの方がCORS有効を設定していない。
でも、設定したら再デプロイするとCORS問題まだ発生している
原因:s3にCORS設定していない。
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"PUT",
"POST",
"HEAD",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"x-amz-request-id",
"x-amz-id-2",
"Content-Length",
"Content-Type",
"Connection",
"Server",
"Etag"
],
"MaxAgeSeconds": 3000
}
]
設定したら、再度テスト見れば正常にアップロードできました!!!
6. まとめ:
APIGateWay → Lambda → S3を概要的に紹介した。
一番留意点はCORS問題です。対応方法も記載している。
ソースコードもGithubに上げましたのでご参考のほどお願い致します。
参考資料
参考ソース
Nguồn: viblo.asia