AWS Lambda のファンクションを TypeScript で作る! 入門編
今回は TypeScript シリーズ第2弾。 AWS Lambda のファンクションを TypeScript 作成する方法について。
最近、サーバーレス化、Micro Services 化の流れで、AWS Lambda を使用する機会が増えてきてるように思います。
煩わしいサーバの管理から解放されてサービスのみに注力できるのはかなり魅力的。今回は Node.js と TypeScript を使って、Lambda ファンクションを作成する方法について解説していきます。
目標は AWS Lambda を使って CloudWatch Logs (ログ) に 天気予報を出力するところまで。
天気予報の取得には お天気Webサービス仕様 - Weather Hacks - livedoor 天気情報 を利用します。実際に取ってくるのはサンプルにある福岡県久留米の天気情報です。(http://weather.livedoor.com/forecast/webservice/json/v1?city=400040)
目次
開発環境導入
Node.js と yarn (パッケージ管理コマンド) の導入
brew install nodebrew yarn echo "PATH=$HOME/.nodebrew/current/bin" >> ~/.bashrc
- apt-get の場合 (Ubuntuなど)
apt-get install nodebrew yarn echo "PATH=$HOME/.nodebrew/current/bin" >> ~/.bashrc
そして、下記コマンドで Node.js 4.3 をインストールして使用するバージョンを 4.3.2 とします。
nodebrew install-binary 4.3.2 nodebrew use 4.3.2
もしここまでで何かしらのエラーがでたら、nodebrew のディレクトリがないことが原因かもしれません。
なので下記コマンドを実行してサイドnodebrew install-binary
を実行し直してみてください。
mkdir -p ~/.nodebrew/src
Lambda ファンクション作成準備
Lambda プロジェクト用のディレクトリを作成する。
今回は天気予報の情報を出力する Lambda なので、weather-lambda
とでもする。
mkdir weather-lambda cd weather-lambda
その後、下記コマンドでプロジェクトの初期化を行う。
yarn init
質問事項を聞かれますが、今回は全部 Enter で OK です。
すると、下記のような package.json
が生成されています。
{ "name": "weather-lambda", "version": "1.0.0", "main": "index.js", "license": "MIT" }
次節に示すパッケージのインストールを行うと、ここにプロジェクトに必要なパッケージ名などが記載されていきます。
必要なパッケージの導入
今回インストールするものは下記4種類です。
- typescript
- request
- @types/node
- @types/request
インストールの際は下記のコマンドでパッケージをインストールする。
yarn add -D typescript @types/node @types/request
yarn add request
TypeScript の設定ファイルを生成
TypeScript のコンパイラオプションを指定するために tsconfig.json
を下記コマンドで作成する。
./node_modules/.bin/tsc --init
すると、下記の様な tscofnig.json
が生成される。
{ "compilerOptions": { "module": "commonjs", "target": "es5", "noImplicitAny": false, "sourceMap": false } }
念のため上記のオプションの説明すると
- module
- target
- ECMAScript のバージョン(“ES3” (default), “ES5”, “ES6”/“ES2015”, “ES2016”, “ES2017” or “ESNext”. )
- noImplicityAny
- 暗黙的に any を使用していたらエラーを出すかどうか
- sourceMap
- ソースマップファイルを生成するかどうか
もっとコンパイラオプションに凝りたい方はコンパイラオプションのドキュメントを参照してみてください。
TypeScript によるファンクションの実装
実装は下記の通り。
単純に request
を使ってお天気Webサービスから情報を GET してきて console.log
でログに吐き出しています。
Lambda では最後に callback を呼ぶのをお忘れなく。
失敗のときは callback の第一引数にエラーを表す文字やエラーオブジェクトを、成功のときは第一引数は null
で第二引数は成功のときの文字を渡します。
import * as request from 'request'; exports.handler = (event: any, context: any, callback: Function) => { const url: string = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400040'; request(url, (err: Error, res: request.RequestResponse, body: any) => { // Return if Error if(err || res.statusCode !== 200) { return callback(err); } // Parse JSON file (body) let jsonFile: any = JSON.parse(body); console.log(jsonFile.title); console.log(jsonFile.description); return callback(null, 'Success!'); }); }
Lambda にアップロードできる形に変換
次にTypeScript のソースを JavaScript にトランスパイルします。そのときに使うのは tsc
*1 コマンド。
インストールしたパッケージのうち bin があるものは ./node_modules/.bin
以下に保存されるのでそちらから実行する。
./node_modules/.bin/tsc index.ts
すると、下記のような index.js
ファイルが生成される。
"use strict"; var request = require("request"); exports.handler = function (event, context, callback) { var url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400040'; request(url, function (err, res, body) { // Return if Error if (err || res.statusCode !== 200) { return callback(err); } // Parse JSON file (body) var jsonFile = JSON.parse(body); console.log(jsonFile.title); console.log(jsonFile.description); return callback(null, 'Success!'); }); };
zip 化
では、Lambda にアップロードするために生成された js ファイルとライブラリを zip にまとめます。ディレクトリ上で下記コマンドを実行。
zip -r lambda.zip *
こうしてできた lambda.zip
を AWS Lambda にアップロードします。
AWS Lambda 上へのアップロード
まず、AWS コンソールにアクセスして Lambda のページにアクセスします。
そして、Create Function
を選択します。
次に、Blanc Function
を選択して Next をクリックします。
それからトリガーの画面です。ここでは S3 のオブジェクトの更新や、1分間隔のイベントなどを Lambda の起動のトリガーに設定することができます。 今回は、サンプルなので特に何も設定せずに Next をクリックします。
次に Lambda ファンクションの設定画面です。
ここでは、Lambda ファンクションの名前、Runtime (実行する環境)、Code の指定方法を選択します。
ファンクションの名前は今回は天気予報の結果を取得してくるので、weatherLambda
としました。それから実行環境は Node.js 4.3
で、 Code entry type を Upload a .ZIP file
にして、Upload ボタンをクリックします。
そしたら、ファイルダイアログが出てくるので先程 zip 化したファイルを選択します。
次に、Lambda を実行するための権限を作成します。今回は単純に AWS Lambda を実行するだけなので、Role の Create a custom role
を選択します。
すると下記のような別画面に遷移します。ただ特にすることもなく、ロール名が lambda_basic_execution
になっていれば許可をクリックします。
すると、Role が existing になって、Existing role が lambda_basic_execution
になっているはずです。
以上で設定は終わりなので、Next ボタンをクリックします。
すると、緑の枠に囲われて Conguraturations! が表示されるので、動作確認のためTest
をクリックします。
次に、Input test event を選択します。ここでは、TypeScript で記述したハンドラのexports.handler = (event: any, context: any, callback: Function) => {
の event に何を渡して実行するか?を選択します。今回は event は使っていないので何でも大丈夫です。ひとまずHello World
を選択しましょう。
すると、下記のようにSuccess!
と log output が表示されます。ここでは少し出力結果が見にくいので click here をクリックして CloudWatch log でログを確認してみましょう。
すると下記のような画面に遷移するはずなので、ログをクリックしましょう。*2
すると下記のように詳細なログを確認することができます。
ログを確認してみると、福岡県久留米の天気と表示されていることや福岡県の天気が表示されていることが確認できるはずです。
以上までが TypeScript で作る簡単な Lambda のサンプルアプリケーションです。
おわりに
今回はサンプルとして、簡単なアプリケーションを Lambda と TypeScript を使って作成しました。
TypeScript なのにあまり型を活かせていなかったり、タスクランナーの説明やらを省いてしまいましたが、そのあたりはまた別記事で紹介をしていきたいと思います。
ひとまず、TypeScript でラムダファンクションを作ってみたいという方の導入になれば嬉しいです。
2017年9月20日 追記
yarn が yanr になってたのを修正しました。(酷い…) id:takashima0411 さん、誤字のご指摘ありがとうございました!