LoginSignup
3
1

More than 3 years have passed since last update.

AWS初心者(一ヶ月)がサーバレス開発 ~ API Gateway & Lambda & DynamoDB 編 ~

Last updated at Posted at 2021-03-19

前回に引き続き、AWS を触り始めて一ヶ月強の人間がサーバレス開発します。

脳内作戦会議、再び

静的コンテンツの公開までこぎつけたわけですが、
AWS を触り始めて一ヶ月強の僕には荷が重いままなわけで。
シンプルすぎる仕様は減らせない荷物なわけで。
適当な作戦が思いつかぬまま、下手の考え休むに似たり、と感心する頃には半日経過しちゃってるわけで。

capture_000022.png
  • 作業a : S3 & CloudFront
  • 作業b : API Gateway & Lambda & DynamoDB (本記事)
  • 作業c : CloudWatch と サービス間の接続周り

API Gateway & Lambda & DynamoDB

しっかり休んだところで、やりたいことはコレだ。

  • DynamoDB にテーブル作成
  • Lambda で DynamoDB にデータ投入
  • API Gateway から Lambda を呼び出す

DynamoDB

仕様を再確認する。

capture_000000.png

氏名、メールアドレス、電話番号の3属性、キーはメールアドレスね。
ということで公式チュートリアルを横目に、

dynamo_create1.png

がんばれ、がんばれ

capture_000001.png

がんばれ、がんばれ

capture_000002.png

ドカッと弁当がデカい男を登録できました。
満足。

Lambda

初心に帰れと言わんばかりのメニューアイコンを選択しつつ、
一から自分で頑張って作成するぜ、と意気込みます。

lambda1.png

ランタイムはデフォルトで選択されていた Node.js でいいや。
社内でも「わかりやすいと思うよー」とオススメされたし。

lambda2.png

デフォルトの実行ロールのままだと
ログ出力以外に他のサービスとアレコレできないっぽい。

ということで IAM コンソールに寄り道してロールを作成。

lambda4.png

Lambda に戻ってロールを選択して

lambda5.png

作成すると

lambda6.png

ひとまずできた、が、コレは枠組みでしかないわけで。

そして、Web 上に散らばる先人たちのコードをパッチワークするしかない僕なわけで。
一から自分で頑張ると意気込んだばかりだというのに。

Node.js
const AWS = require('aws-sdk');
const documentClient = new AWS.DynamoDB.DocumentClient();
const util = require('util');

exports.handler = function(event, context, callback) {

    console.log(util.inspect(event, false, null));

    var input_email = (event.body.email) ? event.body.email : "*";
    var input_name  = (event.body.name)  ? event.body.name  : "*";
    var input_phone = (event.body.phone) ? event.body.phone : "*";

    var params = {
        TableName: 'masklottery_entries',
        Item: {
            'email': input_email,
            'name': input_name,
            'phone': input_phone
        },
        ConditionExpression: 'attribute_not_exists(email)'
    };

    var response = {
        "headers": {
            "Content-Type": "application/json",
        },
        "body": ""
    };

    documentClient.put(params, function(err, data) {
        if (err) {
            console.log("***** failure *****");
            console.log(err);
            response.body = JSON.stringify(err);
            callback(null, response);
        } else {
            console.log("***** success *****");
            console.log(data);
            response.body = JSON.stringify(data);
            callback(null, response);
        }
    });
};

先程作成した DynamoDB にデータを追加するコードを作成してみた。
気を使ったトコロは ConditionExpression: 'attribute_not_exists(email)' で、
意味は "キーがDB上に存在しない場合だけ(更新する)" という条件になるみたい。

capture_000000.png

同一メールアドレスでの申込は1回のみ という仕様を取り入れてみました。
同一キーに対して DynamoDB は RDBMS で言う一意制約違反は発生せず上書き更新するらしいので。

テストデータもがんばって作成します。

capture_000018.png

葉っぱ咥えたアイツはどうかな?

capture_000019.png

よしよし、登録できた。
再度実行してみると、

capture_000020.png

うんうん、想定通りエラーになることを確認できた。
アレが2人もいたら迷惑ですよね。

DynamoDB でも確認してみる。

capture_000007.png

葉っぱ咥えたアイツの2人目は見当たらない。
満足。

API Gateway

「これからは HTTP API だ!」なノリで AWS 公式の説明が推してくるけど、
パラメータをアレヤコレヤできないので REST API を選択するわけで。

capture_000025.png

付け加えると、API Gateway からの作成ではなく、Lambda からのトリガーの追加で作成です。
イイ感じに入力の手間が減るのです。

capture_000026.png

メソッドが ANY だけど、DynamoDB に登録するだけの単一機能だし問題はないな。

次に統合リクエストから Lambda プロキシ統合の使用 のチェックを外して

capture_000027.png

パラメータマッピングを仕込む。

capture_000028.png

テンプレートのコードですか?
パッチワークですよ、一から自分で頑張りきれないですよ。
はい、デプロイ。

capture_000032.png

これで HTML の POST でリクエストするパラメータを Lambda で受け取れることになったわけです。

テストは POSTMAN
リクエストパラメータに語尾が「~ずら」のアノ人を仕込むずら。

capture_000030.png

200 でかえってきたずら。

capture_000033.png

再度実行すると

capture_000035.png

想定通りエラーになったずら。

念の為、DynamoDB も。

capture_000034.png

語尾が「~ずら」のアノ人の2人目もいない。
満足。

ということで今回の目的は達した。

株式会社メソドロジック
三嶋 圭 @k-mishima

参考

Class: AWS.DynamoDB.DocumentClient — AWS SDK for JavaScript
Node.js による Lambda 関数のビルド - AWS Lambda
【DynamoDB】updateItemで新規項目を追加しないようにする 〜条件付き書き込み(ConditionExpression)を使って〜 - Qiita
AWS API GatewayでContent-Type:application/x-www-form-urlencoded のPOSTデータを受け取り JSONに変換する - Qiita
【AWS】API GatewayのMapping Templateで、Key=ValueペアをJSONに変換する - Qiita

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1