【後編】AWS LambdaでNode.jsを使いたい人のためのJavaScript入門【実践編】

こんにちは、エムティーアイ ヘルスケア部門 1年目エンジニアの最上です。今回は、前編記事に引き続き、実践編としてLambdaの形式に則って、実際に手を動かせる課題的なものを提供したいと思います。

この記事を読むには、前編記事の内容を理解していることが必要です。

Lambda

初期テンプレート

LambdaをNode.jsで書く場合、初期コードとして下記が提供されています。

exports.handler = (event, context, callback) => {
    // TODO implement
    callback(null, 'Hello from Lambda');
};

ここではアロー関数が使われていますが、わかりやすく書き直すと下記のようになります。

exports.handler = function(event, context, callback){
    // TODO implement
    callback(null, 'Hello from Lambda');
};

Lambdaでは引数が3つ渡されているfunctionが実行されます。

引数

event(object)

Lambdaはイベントドリブンなファンクションです。そのイベントがこのevent変数に渡されてLambdaが実行されます。どういうイベントをフックして起動したかによってeventの中身が変わります。必ずobject型です。

よくやるのは、API Gatewayと繋いでWebAPIを作る場合だと思います。この場合、eventにはパラメータやヘッダ、HTTPメソッドなど、主にHTTPリクエスト周りの情報がeventに格納されてLambdaが実行されます(LAMBDAプロキシ統合を利用する場合)。

context(object)

実行時の環境が格納されています。あまり使ったことがないし使うこともおそらくないと思うので今回は割愛します。

callback(function)

callbackはfunction型となります。callbackの第二引数に渡した内容がこのLambdaの返り値となります。簡単に言えば、Lambdaというfuntionの返り値なので、returnみたいなものです(あくまでみたいなもの)。第一引数は基本的にnullです。

API Gateway(LAMBDAプロキシ統合を利用)と繋ぐ場合は、第二引数は決められた要素(statusCode, header, body)を持ったobjectでなければなりません。

利用例

送られてきた文字列の語尾に、「素敵やん・・・」をつけて返すLambdaとします。eventは下記で与えられるとします。

event = {
  "suteki": "丸メガネ"
}

Lambdaは下記のような形になります。非常にシンプルですね。eventからsutekiを取り出します。sutekiがあれば語尾に付けて返すので、"丸メガネ素敵やん・・・"を返します。なければエラーメッセージ"素敵なもんないんか?"を返します。

exports.handler = function(event, context, callback){
  var suteki = event.suteki;
  if(suteki){
    callback(null, suteki + "素敵やん・・・");
  }else{
    callback(null, "素敵なもんないんか?");
  }
};

これをAPI Gatewayと接続する場合は下記の様な形になります。前述の通り、API Gatewayと接続すると必須の要素があり、決められた形のobjectをcallbackに渡す必要があるため、下記のような形になります。

var response = {
  statusCode: 200,
  headers: {},
  body: ""
};

exports.handler = function(event, context, callback){
  var suteki = event.suteki;
  if(suteki){
    response.body = suteki + "素敵やん・・・";
  }else{
    response.statusCode = 400;
    response.body = "素敵なもんないんか?";
  }
  callback(null, response);
};

以上のようにLambdaでは、基本的には引数に与えられたeventの内容をもとに処理を行い、callbackに返り値を渡す流れになります。Lambdaは1つの関数のような形ですね。

実践

JavaScriptに慣れるために、以下ではLambdaではなく、指定された処理を行うJavaScript関数を作ってもらう課題を用意しています。ぜひチャレンジしてみてください!JavaScriptの実行は、下記URLのpaizaを利用してください。ブラウザ上で様々なプログラミング言語を実行できる非常に便利なサービスです。JavaScriptを選択して課題にチャレンジしてみてください。

https://paiza.io/

課題1

以下のコードを実行したときに、lastNameの内容Tanakaが出力される関数getNameを作成してください。

var e1 = {
    "queryString": {
        "lastName": "Tanaka"
    },
    "body": null
};

console.log(getName(e1)); // Tanaka

課題2

以下のコードを実行したときに、firstNameの内容Taroが出力される関数getNameを作成してください。ただし、課題1で作成したコードを追記修正して作成してください。

※ object型がstring型になっている場合、stringからobjectに変換するにはJSON.parse(string)を利用すれば、返り値としてobjectが得られる。

var e1 = {
    "queryString": {
        "lastName": "Tanaka"
    },
    "body": null
};

var e2 = {
    "queryString": null,
    "body": '{"firstName": "Taro"}'
};

console.log(getName(e1)); // Tanaka
console.log(getName(e2)); // Taro

実践の答え

課題1

function getName(event){
    var queryString = event.queryString;
    if(queryString && queryString.lastName){
        return queryString.lastName;
    }
    return "bad request";
}

var e1 = {
    "queryString": {
        "lastName": "Tanaka"
    },
    "body": null
};

console.log(getName(e1));

課題2

function getName(event) {
   var queryString = event.queryString;
   if (queryString && queryString.lastName) {
       return queryString.lastName;
   }
   var body = JSON.parse(event.body);
   if (body && body.firstName) {
       return body.firstName;
   }
   return "bad request";
}

var e1 = {
   "queryString": {
       "lastName": "Tanaka"
   },
   "body": null
};

var e2 = {
   "queryString": null,
   "body": '{"firstName": "Taro"}'
};

console.log(getName(e1));
console.log(getName(e2));

おわり。