LoginSignup
4
0

More than 3 years have passed since last update.

サーバレスフレームワークでCRUDを作る

Posted at

サーバレスフレームワークでCRUDを作っていきます

使うツール

  • serverless framework

サーバレスフレームワークを使うとyamlファイルで開発環境が作れるので、人的なミスを減らせてコード管理が楽になります。

使用するサービス

  • iam
  • lambda
  • api gateway
  • dynamodb
テーブルのスキーマ
id: String
name: String
text: String
date: Number

読み取り機能

documentClientのgetメソッドを使います

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

const Dynamo = {
  get: async (id, TableName) => {
    const params = {
      TableName,
      Key: { id }
    };
    const data = await documentClient
      .get(params)
      .promise();

    if (!data || !data.Item) {
      throw Error(`${TableName}${id}がありません`);
    }

    return data.Item;
  }
};
module.exports = Dynamo;

getKeijibanPosts.js
const Responses = require('../common/API_Responses');
const Dynamo = require('./common/Dynamo');
const TableName = process.env.tableName;

exports.handler = async (event, context, callback) => {
  console.log('event', event);

  if (!event.pathParameters || !event.pathParameters.id) {
    // idが渡されて無い
    return Responses._400({ message: 'idを指定してください' });
  }
  const id = event.pathParameters.id;
  const res = await Dynamo.get(id, TableName).catch(err => {
    console.log('error =', err);
    return null
  });

  // idが存在しない時
  if (!res) {    
    return Responses._400({ message: '指定したidのデータは存在しません' });
  }
  return Responses._200(res);
}

serverless.yml
service: kani-keijiban
frameworkVersion: '2'

provider:
  name: aws
  runtime: nodejs12.x
  stage: test
  region: us-east-1
  environment:
    tableName: ${self:custom.tableName}
  iamRoleStatements:
    - Effect: Allow
      Action: 
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem

      Resource: 
        !GetAtt KaniKeijibanDB.Arn
custom:
  tableName: KaniPosts

functions:
  getKeijibanPosts:
    handler: lambdas/endpoints/getKeijibanPosts.handler
    events:
      - http:
          path: api/posts/{id}
          method: get
          cors: true
resources:
 Resources:
   KaniKeijibanDB:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5

書き込み機能

documentClientのputメソッドを使います

serverless.ymlのfuncitonsにコードを追加

  createKeijibanPosts:
    handler: lambdas/endpoints/createKeijibanPosts.handler
    events:
      - http:
          path: api/posts
          method: post
          cors: true

Dynamo.jsのgetメソッドの下に追加

put: async (item, TableName) => {
    if (!item.id) {
      throw Error('idがありません');
    }

    const params = {
      TableName,
      Item: item
    };

    const data = await documentClient
      .put(params)
      .promise()

    return data;
  }

createKeijibanPosts.jsを新たに作成

const Responses = require('../common/API_Responses');
const Dynamo = require('../common/Dynamo');
const TableName = process.env.tableName;

exports.handler = async (event, context, callback) => {
  console.log('event', event);
  const item = JSON.parse(event.body);
  const res = await Dynamo.put(item, TableName).catch(err => {
    console.log('error =', err);
    return null
  });

  // 作成に失敗した時
  if (!res) {    
    return Responses._400({ message: '作成に失敗しました' });
  }
  return Responses._200(res);
}

これで追加機能ができました。

更新機能を作成

documentClientのupdateメソッドを使います

serverless.ymlのfunctionsに追加

  updateKeijibanPosts:
    handler: lambdas/endpoints/updateKeijibanPosts.handler
    events:
      - http:
          path: api/posts/{id}
          method: put
          cors: true

Dynamo.jsのputメソッドの下に追加
※(textがlambdaの予約語と被ってしまったので'#tx'でプレースホルダーを使ってます)

  update: async ({ id, tableName, updateKey, updateValue }) => {
    const params = {
      TableName: tableName,
      Key: {
        id
      },
      UpdateExpression: `set #tx = :updateValue`,
      ExpressionAttributeNames: {
        '#tx': updateKey
      },
      ExpressionAttributeValues: {
        ':updateValue': updateValue
      },
    };

    const res = await documentClient
      .update(params)
      .promise();

    return res;
  },

updateKeijibanPosts.jsを新たに作成

const Dynamo = require('../common/Dynamo');
const Responses = require('../common/API_Responses');

const TableName = process.env.tableName;

exports.handler = async (event, context, callback) => {
  const id = event.pathParameters.id;

  // return the data
  const { text } = JSON.parse(event.body);
  const updateParams = {
    id,
    tableName: TableName,
    updateKey: 'text',
    updateValue: text
  };

  const res = await Dynamo.update(updateParams);
  console.log('res = ', res);
  return Responses._200({});
}

これで更新機能ができました。

削除機能

documentClientのdeleteメソッドを使います

serverless.ymlのfunctionsに追加

  deleteKeijibanPosts:
    handler: lambdas/endpoints/deleteKeijibanPosts.handler
    events:
      - http:
          path: api/posts/{id}
          method: delete
          cors: true

Dynamo.jsのupdateメソッドの下に追加

 delete: async (id, TableName) => {
    const params = {
      TableName,
      Key: { id }
    };
    const data = await documentClient
      .delete(params)
      .promise();

    return data;
  },

deleteKeijibanPosts.jsを新たに作成

const Dynamo = require('../common/Dynamo');
const Responses = require('../common/API_Responses');

const TableName = process.env.tableName;

exports.handler = async (event, context, callback) => {
  const id = event.pathParameters.id;

  // return the data

  const res = await Dynamo.delete(id, TableName);
  console.log('res = ', res);
  return Responses._200(res);
}

動作確認

  • 読み込み
    スクリーンショット 2020-12-13 4.29.35.png

  • 作成
    スクリーンショット 2020-12-13 6.57.09.png

  • 編集
    スクリーンショット 2020-12-13 6.58.17.png

  • 削除
    スクリーンショット 2020-12-13 6.55.32.png

まとめ
簡単なCRUD操作を知ることができた。
serverless frameworkのenvironmentに変数を書くとlambdaのprocess.envから読み込むことができる。

github: https://github.com/satouyuuki/lambda-keijiban

4
0
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
4
0