初めてのJavaScript、初めてのAWS Lambda
はじめに
佐々木です。開発経験も無くJavaScriptを触ったこともない僕ですが、どうしてもAWS lambdaを触ってみたかったので、四苦八苦しながらやってみました。
すでにバリバリ活用しているブログ記事がたくさん出ていますが、本記事は本当に何もわからない僕がよちよち歩きしている内容ですので、深いところは期待しないでください。そして識者のツッコミをお待ちしております。
AWS lambdaの基本的な使い方は以下の記事をご参照ください。
やってみる
MBAにnode.jsをインストールする
とりあえず簡単な構文チェックだけでも手元でやりたいので、MBAにbrewを使ってnode.jsをインストールします。
$ brew install node $ node -v v0.10.32
簡単なスクリプトを動かしてみます。
$ vi hello.js console.log('Hello World'); $ node hello.js Hello World
これでとりあえず構文チェックは出来ます。もっと良いデバッグ方法があれば是非教えてください。
外部モジュールを使ってみる
AWS lambdaではAWSマネージメントコンソール上で直接jsスクリプトを書く以外に、外部モジュールもまとめてzip化してアップロードすることができます。
外部モジュールを使う場合には、lambdaスクリプトを作成するプロジェクトディレクトリを作ります。
$ mkdir myfunc $ cd myfunc
外部モジュールをプロジェクトにインストールします。今回はasyncを使ってみました。
$ npm install async
そしてlambdaスクリプトを作成します。
$ vi index.js var async = require('async'); exports.handler = function(event, context) { async.series([ function (callback) { console.log("one"); callback(null, "one"); }, function (callback) { console.log("two"); callback(null, "two"); }, function (callback) { console.log("three"); callback(null, "three"); } ], function (err, results) { if (err) { throw err; } console.log('all done. ' + results); }); };
lambdaスクリプトと外部モジュールをZIP化します。この時プロジェクトディレクトリごとzip化(zip -r myfunc.zip ./myfunc/)すると、ファイルが見つからない(Can't find module)エラーになってしまいますので、以下のようにlambdaスクリプトと外部モジュールディレクトリを指定してzip化します。
$ zip -r myfunc.zip index.js node_modules
このZIPをAWS lambdaにアップロードして実行すると、以下のように動きます。
Logs ---- START RequestId: bf1f1533-75f5-11e4-a765-67c132e1225f 2014-11-27T05:24:52.586Z bf1f1533-75f5-11e4-a765-67c132e1225f one 2014-11-27T05:24:52.625Z bf1f1533-75f5-11e4-a765-67c132e1225f two 2014-11-27T05:24:52.625Z bf1f1533-75f5-11e4-a765-67c132e1225f three 2014-11-27T05:24:52.625Z bf1f1533-75f5-11e4-a765-67c132e1225f all done. one,two,three Process exited before completing request END RequestId: bf1f1533-75f5-11e4-a765-67c132e1225f REPORT RequestId: bf1f1533-75f5-11e4-a765-67c132e1225f Duration: 220.41 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 9 MB Message ------- Process exited before completing request::
ちゃんと動きました!
AWS SDKを使ってみる
さて、ようやっとlambdaっぽい話になります。lambdaスクリプトからAWS SDKを使ってみました。やっているのは
- S3 BucketにObjectがPUTされる。
- 同じBucketに、ファイル名に"copy-"と付与して、コピーを置く。
という流れです。GETとPUTの間にサムネイル作成やリサイズなどの画像変換処理などを組み込むと、さらにlambdaっぽいですね。今度やってみます。
var async = require('async'); var AWS = require('aws-sdk'); var s3 = new AWS.S3(); exports.handler = function(event, context) { var Bucket = event.Records[0].s3.bucket.name; var srcKey = event.Records[0].s3.object.key; var dstKey = "copy-" + srcKey; if (srcKey.substr(0,5) == 'copy-') { return; } async.waterfall([ function download(callback) { console.log('download start:' + srcKey); s3.getObject({ Bucket: Bucket, Key: srcKey }, function(err, data) { if (err) { callback(err); } try { callback(null, data); } catch (e) { callback(e); } } ); }, function upload(arg1, callback) { console.log('upload start:' + dstKey); console.log('data:' + arg1.Body); s3.putObject({ Bucket: Bucket, Key: dstKey, Body: arg1.Body }, function(err, data) { if (err) { callback(err); } try { callback(null); } catch (e) { callback(e); } } ); } ], function (err) { if (err) { console.log('Error:' + err); } console.log('all done. '); }); };
これをAWS lambdaにアップロードし、S3にファイルをPUTすると、自動的にファイルがコピーされます。
わーい動いたよー!
まとめ
AWS SDKと外部モジュールの活用がlambdaのキモかなと思いました。それにしても、これまでRubyしかやってこなかったためJavaScriptについては全く知識がなかったのですが、まだ全然わかりません。ちゃんと基礎から勉強しようと思います。