はじめに
前回の記事でServerless FrameworkでLambdaの開発環境を構築しました。
引き続きServerless Frameworkの勉強ということで、Lambda(Node.js), API Gateway, DynamoDBの構成でREST APIを作成してみることにしました。
実装
Lambda関数の中身をjsファイル、構築するリソースの設定をserverless.ymlに記述します。
Lambda関数の作成
REST APIを実装するにあたり、データ作成(Create), 全データ取得(List), データ取得(Get), データ更新(Update), データ削除(Delete)の機能が必要です。
そのため、各機能ごとにLambda関数を作成する必要があります。
それぞれの関数を説明すると長くなるので、データ更新用の関数(create.js)のみ説明します。
create.js
'use strict';
const uuid = require('uuid');
const AWS = require('aws-sdk');
const dynamoDb = new AWS.DynamoDB.DocumentClient(); //ドキュメントクライアントを使用してNode.jsでDynamoDBにアクセス
module.exports.create = (event, context, callback) => {
const timestamp = new Date().getTime();
const data = JSON.parse(event.body); //JSONをJSのオブジェクトに変換
//textがstringじゃないときにエラーを返す(バリデーション)
if (typeof data.text !== 'string') {
console.error('Validation Failed');
callback(null, {
statusCode: 400,
headers: { 'Content-Type': 'text/plain' },
body: 'Couldn\'t create the todo item.',
});
return;
}
//テーブル名(TableName)と各カラム(Item)のオブジェクト
const params = {
TableName: process.env.DYNAMODB_TABLE,
Item: {
id: uuid.v1(),
text: data.text,
checked: false,
createdAt: timestamp,
updatedAt: timestamp,
},
};
//DynamoDBへのデータ保存
dynamoDb.put(params, (error) => {
//エラー処理
if (error) {
console.error(error);
callback(null, {
statusCode: error.statusCode || 501,
headers: { 'Content-Type': 'text/plain' },
body: 'Couldn\'t create the todo item.',
});
return;
}
//処理成功時のレスポンス
const response = {
statusCode: 200,
body: JSON.stringify(params.Item), //JSオブジェクトをJSONに変換
};
callback(null, response);
});
};
Node.jsからDynamoDBにアクセスするために、ドキュメントクライアントを利用します。
const dynamoDb = new AWS.DynamoDB.DocumentClient();と定義することで、dynamoDb.get(データ取得)、dynamoDb.put(データ保存)のようにJSでDynamoDBのデータの基本操作を行うことができます。
データ保存を行うためには、テーブル名(TableName)とカラム(Item)のオブジェクト(params)を用意してdynamoDb.put(params, (error)のように引数で渡してあげればOKです。
const params = {
TableName: process.env.DYNAMODB_TABLE,
Item: {
id: uuid.v1(),
text: data.text,
checked: false,
createdAt: timestamp,
updatedAt: timestamp,
},
};
dynamoDb.put(params, (error)の中身には、データ保存の処理が失敗したときと成功したときのcallbackを記述します。
処理が成功していれば、ステータスコード(statusCode)と保存内容(body)を返します。
//処理成功時のレスポンス
const response = {
statusCode: 200,
body: JSON.stringify(params.Item), //JSオブジェクトをJSONに変換
};
callback(null, response);
serverless.ymlの作成
API GatewayやDynamoDBのリソースを構築するために、serverless.ymlを記述します。
API Gatewayの構築
公式ドキュメントを参考に、Lambda関数のトリガーイベントとしてAPIGatewayを作成します。
functions: #Lambdaの構築
create: #関数名を指定
handler: todos/create.create #handler関数の指定(ディレクトリパス.モジュール名)
events: #Lambdaのイベントトリガーを指定
- http: #httpイベントをトリガとしてAPI Gatewayを構築
path: todos #リソースの指定
method: post #メソッドの指定
cors: true #cors有効/無効の指定
DynamoDBの構築
DynamoDBの構築についても、公式ドキュメントを参考にします。
resources: #リソースの構築
Resources:
TodosDynamoDbTable: #DynamoDBの構築
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
IAM設定
LambdaからDynamoDBにアクセスするための権限を付与するために、ProviderにiamRoleStatementsを追記します。
provider:
name: aws
runtime: nodejs12.x
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: 'arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}'
デプロイ
以下のコマンドでデプロイを行います。
sls deploy -v
AWSコンソールのLambdaを開くと、作成した関数がデプロイされているのを確認できます。
API Gatewayを開くとdev-serverless-rest-api-with-dynamodbが作成されています。
また、DynamoDBにもテーブルが作成されます。
動作確認
insomniaを使って挙動をみてみます。
エンドポイントはデプロイの際にターミナルに表示されたものを使います。
endpoints:
POST - https://zb6e0z65ka.execute-api.us-east-1.amazonaws.com/dev/todos
GET - https://zb6e0z65ka.execute-api.us-east-1.amazonaws.com/dev/todos
GET - https://zb6e0z65ka.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
PUT - https://zb6e0z65ka.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
DELETE - https://zb6e0z65ka.execute-api.us-east-1.amazonaws.com/dev/todos/{id}
試しにPOSTリクエスト(Create)を飛ばしてみると、200 OKとレスポンスが返ってきます。
また、DynamoDBのテーブルにはデータが追加されています。
おわりに
Serverless Framework超便利だね。
参考資料
↧