AWS Lambdaで使う関数をローカルでテストするサーバーを建てる。
AWS Lambda + AWS Api Gateway + AWS DynamoDBでなにかをつくることにはまっています。
AWS Lambdaで使う関数自体はmochaなどでテストできますが、実際にブラウザから叩くテストをローカルでしたいと思いました。
そこでNode.jsで簡単なサーバーを建てます。
まず、AWS Lambdaはこのような関数です
"use strict"; const Workbook = require('./src/workbook').Workbook; const Marker = require('./src/marker').Marker; exports.handler = (data, context, callback) => { let workbook = new Workbook(data); let marker = new Marker(workbook, data); marker.mark((result) => { if (result) { context.succeed({result: 'correct', data: marker.explain()}); } else { context.fail(JSON.stringify({result: 'incorrect', data: marker.explain()})); } }); };
Workbook
やMarker
がDynamoDBにアクセスします。環境変数を使って、内部で参照ファイルを切りかえ、ローカルのDynamoDBにアクセスするようにしているので、そちらは大丈夫です。
テストサーバーです
サーバー側の言語をまともに触ったのはNode.jsがはじめてで、はじめて書いたのもこのような簡易なサーバーでした。非常に懐かしいですね。
import * as http from 'http'; import * as qs from 'querystring'; import * as marker from '../marker/index'; http.createServer(function (req, res) { if (req.method !== 'POST' && req.method !== 'OPTIONS') { res.end(''); return; } res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'POST'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); res.setHeader('Content-Type', 'application/json'); if(req.method === 'OPTIONS'){ res.end(``); return; } let body = ''; req .on('data', (data) => { console.log('data', data); body += data }) .on('end', () => { qs.parse(body); marker.handler(JSON.parse(body), { succeed: (data)=> { res.end(JSON.stringify(data)); }, fail: (stringifiedData)=> { res.end(stringifiedData); } }); }); }).listen(process.env.PORT || 3080, '127.0.0.1');
OPTIONS
によるプリフライト対応処理を追加しました。(昨日は素のPOST
だけ飛んでたのにな……)
まずPOST
とOPTIONS
以外はハネます。
つぎに、データの整形ですね。こういうのは自動でやってくれないんでしょうか。
marker.handler
がAWS Lambdaでの関数本体なので、そこへデータを投げます。
context.succees
とcontext.fail
で関数を終了するつくりなので、そこに関数を妖異します。その関数呼び出しをもってJSONレスポンスを作成します。
実際のfail
では{errorMessage: 引数}
というレスポンスになりますが、これはAWS Api Gatewayで整形します。ので、それを踏まえたJSONとします。
$ TEST=true babel-node test-server/index.js
テストできた
これでブラウザ側からSuperagentなどを使いPOST
すると、実際のレスポンスが得られるようになりました。
クリッククリックで行うテストがはかどりますね。