DynamoDBが更新されたらS3にJSONを吐いてGETで呼べるようにする


前回記事S3へ保管したメールをパースしてDynamoDBへ入れてみる の続きです。

これまでの記事でAWS SESで受信したメールをパースして、Lambdaを使ってDynamoDBヘ格納できるようになりました。

図解

だいぶ荒いですが、図解するとこんな感じです。

主旨

今更ですが主旨としては「福岡市の消防車や救急車が出動したら配信されるメールをクラウド上で受信して、情報を整理して直近10件の情報を返すAPIを作ろう!お金ないしサーバレスにしよう!」というものです。

今回やる事

今回はついにAPIっぽい感じに出力します。
手段としては、DynamoDBの「トリガー」を使い、DynamoDBに更新がかかったらLambdaをキックし、DyanmoDBから直近10件のデータを取得してS3にJSONファイルとして書き込みます。

図にするとこの6番ですね。

DynamoDBのトリガー

DynamoDBに更新がかかったらLambdaがキックされるように設定します。

トリガータブから「トリガーの作成」を選びます。
新規でLambdaを作成するか、既存のLambdaを選択することが可能です。
今回は既存のLambdaを呼びます。


シンプルでいいですね。実行したいLambdaとバッチサイズを選びます。
バッチサイズとは、同時にLambdaに投げられる数らしいです。
1件ずつ処理したい場合は1とかにすればいいと思いますが、今回は最新の状態が維持できればいいので100でいいのかなと。(データ取り直してるし。。。)

Lambda

今回はこんな感じのコードになりました。

'use strict';

var request = require('request');
var aws = require('aws-sdk');
var unmarshalItem = require('dynamodb-marshaler').unmarshalItem;
var tableName = "Dispatches";
var dynamo = new aws.DynamoDB();
var s3 = new aws.S3();

var param = {
    TableName: tableName,
    Limit: 10
};

exports.handler = (event, context, callback) => {
  dynamo.scan(param, function(err, data) {
    if (err) {
      context.fail(err);
    } else {
      var items = data.Items.map(unmarshalItem);
      s3.putObject({
        Bucket: YOUR_BUCKET_NAME,
        Key: YOUR_FILE_NAME,
        ContentType: 'application/json',
        Body: JSON.stringify(items)
      }, function(err, data){
          if(err){
              console.log("error" + err);
          }else{
              console.log("worked, data: "+JSON.stringify(data));
          }
      });
      context.succeed(items);
    }
  });
};

DynamoDBから10件取ってきて、S3にPUTしているだけですね。シンプル。

メールの受信を待ってみると、無事にJSONファイルがS3に吐かれました。
ちなみにこのS3のバケットは静的ウェブサイドホスティングを有効にしているので、GETで呼べます。簡易API!!

静的ウェブサイドホスティングについてはAWSのS3で静的Webサイトを公開する手順まとめをご参照ください。

このような手法を取ると、簡単なデータ処理やAPI提供はサーバレスな感じで(安価で)提供できそうですね。

と思ったらこれ。。。直近10件になってないですね。。。修正しないと。。。