31
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS LambdaAdvent Calendar 2017

Day 19

バイナリデータ(画像)をAPIGatewayとLambdaを組み合わせてS3にPUTする

Posted at

はじめに

以前、SORACOM BeamでバイナリデータをAPIGateway経由でS3にアップロードするという記事を書いたのですが、今回はその記事の続編です。

別のアドカレでもLambdaの素晴らしさを少し語らせていただいたのですが(これ)、Lambdaはかなり便利だと思ってます!。私が今携わっている案件でも、常に十数台のLambdaが立ち上がって処理をしてくれています。

ある日の私

実際にその構成を使って画像を保存していたのですが、ある日
私「だいぶ溜まってきたしCLIでローカルにダウンロードしよっと」

aws s3 cp s3://bucketName/key ~/image

S3「Access deniedやで」
私「ファッ!?」
という一連の流れがあって、もしかしてこの構成間違ってる?ということに気がつきました。

なにがあった?

それまでの構成では、画像ファイルをバイナリのまま、APIGatewayにSORACOMBeamを通してRESTAPIでPOSTして、そのあとS3にPUTするようにしてました。
しかしそれでは、S3にPUTする際に必要なHeader情報が不足しているようでした。(それならそれでエラー吐いて欲しいものですが…)
果たして不足分のHeader情報を全て網羅できるのだろうか。いやできない。(反語)
※必要なHeader情報は公式ドキュメントを参照。

それじゃあどうする?

「便利なものは 使ってしまえ ホトトギス。」(字余り)

ということで、AWS-SDKでPUTすることにしました。SDKを利用すればHeader情報などをよしなに補ってくれますし、おすし。
そして、便利屋Lambdaさんの登場です。
APIGatewayから一度Lambdaにデータを渡して、LambdaからAWS-SDKを使ってPUTする。という流れです。

以前までの構成は前編を参照してください。

APIGatewayからLambdaを呼び出す

スクリーンショット 2017-12-15 9.36.33.png

設定中に「APIGatewayにLambdaをinvokeする権限渡すけどええか?」と聞かれるのでOKしてあげてください。

マッピングテンプレートの設定

Content-TypeごとにどのようなテンプレートでLambdaに渡すかを設定します。
「Method Request passthrough」を選択しておけば問題ないです。

スクリーンショット 2017-12-15 9.41.37.png

バイナリサポートの設定

バイナリデータを送信するときのContent-Typeを設定しておきます

スクリーンショット 2017-12-15 9.44.40.png

Lambdaの作成

ランタイムはpython2.7です。
先ほどのマッピングテンプレートの形でeventに渡されてきます。

import json
import boto3
import base64

def lambda_handler(event, context):
    print json.dumps(event)
    
    try:
        s3 = boto3.resource('s3')
        bucket = s3.Bucket('bucketName')
        
        # バイナリがBase64にエンコードされているので、ここでデコード
        imageBody = base64.b64decode(event['body-json'])
        
        # リクエストパスを組み合わせてKeyにする
        imagePath = event['params']['path']
        key = imagePath['key'] + '/' + imagePath['name']
        print key
        
        bucket.put_object(
            Body = imageBody,
            Key = key
        )
        print 'success!'
    
    except Exception as e:
        print 'Error!'
        print e

これでLambda経由でS3に画像が保存されます。
SDKを利用してるので、Header情報やmetaデータはよしなにしてくれてます。

さいごに

やっぱりLambdaは便利ですね。

ではまた!

31
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?