Skip to content

Instantly share code, notes, and snippets.

@PhilOwen
Last active December 16, 2017 13:11
Show Gist options
  • Save PhilOwen/0197e3ae9bb5a8a288f72194872f730f to your computer and use it in GitHub Desktop.
Save PhilOwen/0197e3ae9bb5a8a288f72194872f730f to your computer and use it in GitHub Desktop.
AWS LambdaとAPI Gatewayで、サーバレスなウェブAPI

AWSのLambdaで、DynamoDBにデータを突っ込む。 LambdaではPython等も使えるが、昔からあるnodeを素直に使った。 入り口は、インタネットからAPI Gatewayで。

exports.handlerに実行したい関数を設定する。 DynamoDBはスキーマレスで、カラム定義なしに色々データを突っ込める。 が、レコードのカラムには、Sという不思議なものを渡す。

API Gatewayでは、宛先となるリソースやメソッドを定義する。 パラメータは、node側で取り出すのではなく、 Integration RequestでBody Mapping Template というものを定義して取り出す。

{
    "id": $input.json('$.user'),
    "data": $input.json('$.dataBody')
}

のような感じ。
ここでパラメータが合わない場合、 Lambda関数が呼む前にコケて、デバックに苦労する。
また、jQueryでオブジェクトをPOSTするとき、 $.post()ではダメだった。 $.ajax()でパラメータを直接指定しないといけないらしい。

node側ではcontext.fail()するケースもあるが、 その場合でも、ステータスコードはデフォルトだと200 OKになる。 400系にしたければ、明示的にAPI Gatewayの Method Responseに400系を追加する。 それからその400系コードを返すときの条件を Lambda Error Regexに指定する。
今回は作成で、201 Createdが望ましいので、 201になるようにレスポンスの設定をしないといけない。

手間と落とし穴は結構多い。 サーバレスだと安価だし、 技術的にもおもしろい感じではあるが…

'use strict';
const aws = require('aws-sdk');
let db = new aws.DynamoDB();
exports.handler = (event, context) => {
let params = {
TableName: 'abe_log',
Item: {
id: {S: event.id},
data: {S: event.data},
timestamp: {S: new Date().toString()}
}
};
db.putItem(params, err => {
if (err) {
context.fail(err);
} else {
context.succeed("ok!");
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment