目的は、7月にAmazonからAPI Gatewayが発表され、Web上にAWS Lambda + API Gatewayを利用したサーバレスアーキテクチャのサンプルが多数公開されていますが、実際に使ってみないと使い方や特徴が掴めないと思い、お試しでそれらを組み合わせてWebアプリケーションを作ってみました。
今回はその備忘録の意味も込めて記事を書きました。
まず、サーバレスアーキテクチャですが、Web/アプリケーションサーバを利用せずに、Webサービスを構築するというものです。
GoogleのGoogle App Engine(GAE)が先駆けとなり、最近ではAWSでも前述のLambda、API Gatewayを利用することで、このアーキテクチャを採用することができるようになりました。
次のような事がサーバレスアーキテクチャを採用する事で得られる効果だと言われています。
- インフラのリソースや可用性をサービス提供(GoogleやAmazon)側で保証してくれるため、アプリケーション開発に集中可能
- インフラのランニングコスト(仮想サーバ代、運用コスト)が削減可能
特定のイベントをトリガにAWS Lambdaにアップロードしたコード(Node.js/Java/Python)を実行させるコンピューティングサービス。
例えばDB更新をトリガに通知メッセージを出すなど、AWS上の各種サービスリソース同士を柔軟に結びつけることができます。
AWS Lambdaの詳細は下記をどうぞ
https://aws.amazon.com/jp/lambda/details/
Amazon等のクラウドのサービスをREST APIとして公開できるものにしたサービスです。
API Gatewayを利用することで、AWS Lambda で稼働しているコードをREST APIとして公開できるようになりました。
これにより、任意のWebアプリケーションからAPI Gatewayで作成したAPIを実行することで、Amazonが提供するWebサービス(例えばDynamoDB)に簡単に利用できるようになりました。
(今まではAWS SDKを利用する必要があり、なかなか大変だった)
API Gatewayの詳細は下記をどうぞ
https://aws.amazon.com/jp/api-gateway/
アプリケーションは下記を組み合わせた構成としています。
- API Gateway
- Lambda
- S3(HTML + JavaScript)
- DynamoDB
構成自体は良くあるものだと思います。
動きは次のような形になります。
- BeaconBridge から ビーコン検出トリガで WebHook( API Gateway 叩く )
- WebHookトリガで API Gateway がLambdaを起動
- Lambda から DynamoDB ( WebHookのパラメータをパースして必要な情報を格納 )
- S3 に配置した静的サイト(HTML)を取得
- HTML に記載されている JavaScript から API Gateway を叩く
- Lambda から DynamoDB にクエリをかけ、結果をレスポンスに載せる
- API Gateway からのレスポンスで DOM操作( コンテンツ更新 )
DynamoDBを利用するためのSDKには次の2種があります。
- AWS SDK
- DynamoDB Document SDK
サンプルとしてWebサイトに公開されているものの多くは「AWS SDK」を利用したものです。
しかし、AWS上で新規のLambda用のコードを作成するときに選択できるサンプルコード集(blueprint)には、「DynamoDB Document SDK」が利用されています。
この2種のSDKに互換性があれば問題ないのですが、putやquery時のパラメータに、valueの型が必須/不要といった差があり、間違うと当然エラーになります。
(参照するドキュメントにはご注意を!これにハマってそこそこ時間取られました…)
var AWS = require(‘aws-sdk’);
var dynamodb = new AWS.DynamoDB({region: ‘ap-northeast-1’});
// put用パラメータ
var param = {
TableName: ‘your-table-name’,
Item: {
‘user’:{ “S” : “hogehoge” }, // 文字列型を指定
‘id’ :{ “N” : “1” } // 数値型を指定
}
};
dynamodb.putItem(param, function (err, data) {
});
var doc = require(‘dynamodb-doc’);
var dynamodb = new doc.DynamoDB();
// put用パラメータ
var param = {
TableName: ‘your-table-name’,
Item: {
‘user’: ‘hogehoge’,
‘id’ : 1
}
};
dynamodb.putItem(param, function (err, data) {
});
ユーザのAWSの各種サービス利用権限を絞るために、IAM(Identity and Access Management)を利用します。
IAMでLambdaやDynamoDB、API Gatewayの利用を許可していても、Lambdaの実装が進められないという罠がありました。
Lambdaにサービスの利用権限を付与しなければならない為、IAMを利用するための権限も必要という事でした。
ルートアカウントやIAMで全てのサービスを許可されていると気が付きにくい点です。
- インフラ構築が不要になったことで開発者がアプリケーション実装に専念できる
- 小規模なWebアプリケーションならば短期で実装できる
- 従量課金制なので使っていなくても無駄にならない
- リアルタイムWebアプリケーションには不向きだと思われる
- ドキュメントの整備は、もう一歩進んでほしい
- パフォーマンスやスケーラビリティ(AWSが保証してくれるけど、どの程度なのか)
- Cognito等を利用したAPIの認証(今回はお試しなので未考慮だった)
- 既存システムのサーバーレスへの置き換え
- Node.js以外を利用したLambdaの実装