Help us understand the problem. What is going on with this article?

AWS Lambdaのための関数のローカル開発とテスト

More than 5 years have passed since last update.

これは個人の意見/メモであり、所属する組織を代表するものではありません。

サマリ

AWS LambdaのLambda Funcitonをローカルで開発する環境について考えてみた。

なお、このポストの続きをAWS Lambdaの関数をnpmでパッケージ管理に書いています。

大まかな方法

Lambdaでは、例えば以下のような感じで関数を実装してアップロードする。

myFirstLambda.js
var AWS = require("aws-sdk");
var DOC = require("dynamodb-doc");

AWS.config.update({region: "us-west-2"});

exports.handler = function(event, context){
    this.docClient = new DOC.DynamoDB();

    //Do something with DynamoDB

    context.done();
}

で、実行の際にはmyFirstLambda.jsがrequireされてhandlerメソッド(メソッド名はLambdaの設定で変更可能)が呼ばれる、という非常に単純な話(少なくとも外から見る限り)なので、以下のようなドライバスクリプトを書いてあげればOK。

driver.js
//YOUR DATA TO BE PASSED TO LAMBDA FUNCTION.
var event = {
  "Records": [
    {
      "awsRegion": "us-west-2",
      "sequenceNumber": "196800000000000000000374",
      "partitionKey": "2efdb0ea22685b46993e42a67302a001",
      "eventSource": "aws:kinesis",
      "data": "SOME CUSTOM DATA 1"
    }
  ]
};

//BUILD STAB OF context OBJECT.
var context = {
    invokeid: 'invokeid',
    done: function(err,message){
        return;
    }
};


//RUN YOUR HANDLER
var lambda = require("../myFirstLambda");
lambda.handler(event,context);

handlerに渡ってくるeventとcontextというオブジェクトについての補足

  • event: 実際に渡ってくるイベントのデータ(S3のアップデートとかKinesisのレコードとか)。
  • context: Lambda functionの呼び出しコンテキスト。done()というAPIを呼び出すと関数が終了するのだが、コードをちょっと追いきれてないのでとりあえず単純にreturnするだけな感じにstub化。ちなみにcontextオブジェクトのダンプは以下のとおり。done()の中で呼び出されているpostDone()は後で追ってみる。
{
    invokeid: 'STRING', // Lambda functionの呼び出しIDのようなもの(恐らく呼び出しごとにユニーク)
    done: function (err, message) {
        if(doneStatus) {
            return;
        }
        doneStatus = true;
        var error = null;
        if(!(typeof err == "undefined" || (typeof err == "object" && !err))) {
            error = util.format(err);
            console.log(error);
        }
        /*
        * use a timeout to perform the operation once the user gives up control of the event thread
        * This is how HTTP handler works right now
        */
        setTimeout(function() {
            postDone(error, message);
       }, 0);
    }
}

というわけで、こんな感じにドライバスクリプトを準備してあげれば、コード書いてLambdaにアップしてSave & Invokeして・・・みたいなのを繰り返さずにもローカルで開発ができるよという話でした。

テストを書く

ドライバが書けたので、ちょっと手を加えればテストも書ける。

test/basic.js
var assert = require('assert');

//YOUR_EVENT_OBJECT
var data = {};

var context = {
    invokeid: 'invokeid',
    done: function(err,message){
        return;
    }
};

describe('myFirstLambda',function(){
    it('Should have docClient', function(){
        var lambda = require("../myFirstLambda");
        lambda.handler(data,context);
        assert(lambda.docClient);
    });
});

で、package.jsonにこんな感じにテスト実行と依存関係について定義しておけばLambda用の関数をnpmパッケージとして 管理できる・・・気がする。

package.json

{
  "name": "myFirstLambda",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "aws-sdk":"2.*",
    "dynamodb-doc":"1.*"
  },
  "devDependencies": {
    "mocha": "*",
    "eslint": "*",
    "istanbul": "*"
  },
  "scripts" : {
    "test" : "npm -s run-script lint && npm -s run-script unit",
    "unit" : "istanbul `[ $COVERAGE ] && echo 'cover _mocha' || echo 'test mocha'` -- test test/basic",
    "lint" : "eslint ./*.js"
  }
}

あとはscriptに

  • build: 必要なファイルをzipしてpkg/配下に吐き出す
  • deploy: AWS Lamdaにアップロードする

あたりを付け足してあげるとよりパッケージ管理が楽になりそうなんだけど、それはまた今度。

追記

続き書いた: AWS Lambdaの関数をnpmでパッケージ管理

imaifactory
すべての投稿は個人的意見であり、所属する企業や団体を代表するものではありません。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away