LoginSignup
1
2

More than 3 years have passed since last update.

【NodeJS】AWS Lambda+APIGateway+DynamoDBでTODOアプリを作成

Last updated at Posted at 2020-04-12

はじめに

サーバーレスを趣味で始めてみたので、勉強がてらAWS Lambda+APIGateway+DynamoDBでTODOアプリを作成し始めました。
個人のメモとして、サーバー側とクライアント側での処理を記事にまとめます。(まだ作成途中です)

概要

Lambdaで使用する言語はNode
DynamoDBはidとtodoという項目のみを持ちます。
テーブル名は「todoTable」
今回は、GETとPOSTのみを実装します。

Lambdaで関数作成

本来であれば1つの関数にまとめたかったのですが、GETメソッドであることをLambdaに渡す方法がわからず、ひとまず関数を分けました。

まずはGETメソッドから。
単純に全てのカラムを取得します。(本来はあまりscanは使わない方がいいらしいが)

const AWS = require('aws-sdk')
const dynamo = new AWS.DynamoDB.DocumentClient()

exports.handler = (event, context, callback) => {
    const httpMethod = event.httpMethod
    const params = {
        'TableName': 'todoTable'
    }
    dynamo.scan(params, function (err, data) {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data.Items)
        }
        callback(null, response)
    })
};

クライアント側でbodyからtodoListを取り出し表示するようにします。

続いてPOSTメソッド。

const AWS = require('aws-sdk')
const dynamo = new AWS.DynamoDB.DocumentClient()

exports.handler = (event, context, callback) => {
    const params = {
        'TableName': 'todoTable',
        'Item': {
            'id': event.id,
            'todo': event.todo
        }
    }
    dynamo.put(params, function(err, data) {
        if (err) {
            console.log('error')
        } else {
            console.log('success')
            const response = {
                statusCode: 200,
                body: JSON.stringify(data)
            }
            context.done(null, response)
        }
    })
};

try-catchでやるべきですが、今回は簡略化のためこのような実装にしました。(あとで全てtyr-catchに直します)
なぜかここでcallbackを使うと怒られました。
理由分かる方、教えていただきたいです。

あとはAPIGatewayでこれらの関数を各メソッドに割り当てて、デプロイしてください。
詳細は省きます。

クライアントサイド

今回はjQueryは使わずにXMLHttpRequestを使用して実装します。

まずは、画面がロードされた際にGETメソッドでテーブルの項目を取得し、表示をします。

window.onload = () => {
    const request = new XMLHttpRequest()

    request.open('GET', 'https://ほにゃらら.amazonaws.com/dev', true)
    request.responseType = 'json'

    request.onload = event => {
        const data = this.response
        const todoList = JSON.parse(data.body)
        for (task of todoList) {
            const item = task.todo
            // HTMLのulにliを突っ込むだけのメソッド
            createTodoList(item)
        }
    }

    request.send()
}

特に難しい部分はなし。

続いて、TODOを追加した際に走るイベントを追加。

// addというinputタグにイベントを追加
const addTask = document.querySelector('.add')
addTask.addEventListener('submit', e => {
    e.preventDefault()

    const id = Math.random().toString(36).slice(-8);
    const task = addTask.add.value.trim()
    const item = {
        'id': id,
        'todo': task
    }

    const request = new XMLHttpRequest()
    request.open('POST', 'https://ほにゃらら.amazonaws.com/dev/insert', true)
    request.setRequestHeader('Content-Type', 'application/json' );

    request.send(JSON.stringify(item))

    if (task.length){
        createTodoList(task)
        addTask.reset()
    }
})

これで完成です。サーバーレスは短時間で割といろいろできて楽しいですね!

躓いたところ

CORS問題

Access-Control-Allow-Origin 

これを理由にずっと怒られていました。
↓参考記事
【解説付き】chromeでXMLHttpRequestをローカルのファイルで行う方法
AWS API Gateway クロスドメイン通信

XMLHttpRequestのパラメータの渡し方

現在のコード

request.send(JSON.stringify(item))

過去のコード(エラー発生)

request.send(item)

JSON形式にしておらず、30分くらい悩まされていました。。。

終わり

今後はUPDATE、DELETEの実装をし、全て1つの関数にまとめたいと思っています。
それが終わったらなんかしらアプリ作ってみようかな。

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