2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Serverless FrameworkでREST APIを作成してみた (Lambda, API Gateway, DynamoDB, Node.js)

Posted at

はじめに

前回の記事で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にアクセスするための権限を付与するために、ProvideriamRoleStatementsを追記します。

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を開くと、作成した関数がデプロイされているのを確認できます。
スクリーンショット 2021-05-01 8.53.48.png

API Gatewayを開くとdev-serverless-rest-api-with-dynamodbが作成されています。
スクリーンショット 2021-05-01 8.57.35.png

また、DynamoDBにもテーブルが作成されます。
スクリーンショット 2021-05-01 9.01.09.png

動作確認

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とレスポンスが返ってきます。
スクリーンショット 2021-05-01 9.34.55.png

また、DynamoDBのテーブルにはデータが追加されています。
スクリーンショット 2021-05-01 9.38.30.png

おわりに

Serverless Framework超便利だね。

参考資料

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?