まえがき
Serverless FrameworkとAPI Gatewayで画像をダウンロードするAPIを作ってみました。
ネット上の情報だとうまくいかなかったので、試行錯誤を繰り返すことになり大変でした。
ソース
手順
Serverless Frameworkインストール
npm install -g serverless
プロジェクト作成
serverless create --template aws-nodejs --name serverless-image-dl-api --path serverless-image-dl-api
Serverless FrameworkにAWSの認証情報を設定
AdministratorAccessポリシーを付与したIAMユーザーを用意して、設定します。
serverless config credentials --provider aws --key YOUR_ACCESS_KEY_ID --secret YOUR_SECRET_ACCESS_KEY
handler.jsを修正
S3から取得した画像をbase64に変換してリターンしています。
handler.js
'use strict';
const S3 = require('aws-sdk/clients/s3');
const s3 = new S3({
apiVersion: '2006-03-01',
region: 'ap-northeast-1',
});
module.exports.getImage = async () => {
const params = {
Bucket: 'apigateway-test-20211111',
Key: 'test.png',
};
const data = await s3.getObject(params).promise();
return data.Body.toString('base64');
};
serverless.ymlを修正
・contentHandling: CONVERT_TO_BINARY
を設定することで、Lambdaのレスポンス(base64)がバイナリに変換されます。
・integration: lambda
を設定することでcontentHandling: CONVERT_TO_BINARY
が有効になります。
serverless.yml
service: serverless-image-dl-api
frameworkVersion: '2'
provider:
name: aws
runtime: nodejs12.x
lambdaHashingVersion: 20201221
region: ap-northeast-1
stage: dev
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
Resource: 'arn:aws:s3:::apigateway-test-20211111/*'
functions:
getImage:
handler: src/functions/handler.getImage
events:
- http:
path: getImage
method: get
cors: true
response:
headers:
Content-Type: "'image/png'"
contentHandling: CONVERT_TO_BINARY
integration: lambda
S3に画像をアップロード
apigateway-test-20211111というバケットを作成。
test.pngというファイルをアップロード。
デプロイ
serverless deploy
動作確認
デプロイ時に出力されるURLにブラウザからアクセス。
画像が表示されれば成功。
リソースの削除
serverless remove