Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

AWS Lambdaを使ってサーバレスアプリを作成(CRUDのR)

記事を閲覧いただき、ありがとうございます。中村です!!
2020年10月にAWSエンジニアとして転職したので、AWSの予習も兼ねてLambdaを使ったアプリ作成について書いきます。

AWS Lambdaとは?

ここでつらつら説明するより公式動画の方がわかりやすいという結論に至りました。まずはご覧ください。



以下を使用して作成ます。

フロントエンド : Vue.js
AWS(インフラ) : S3, API Gateway, Lambda, DynamoDB

構成

構成はこんな感じです。
DBはDynamoDB、アプリケーションサーバの代わりにlambdaを使ってサーバレスにする。
lambdaプログラムをAPI Gatewayと連携し、APIとして呼べるようにする。
Webサーバのように使えるS3にフロントエンドのプログラムをデプロイする。
スクリーンショット 2020-10-17 16.27.34.png

画面

画面こんな感じです。 
めちゃシンプルですが、自分の尊敬する人/好きな有名人などの情報を記録するアプリを作ります。
(余談:gifって初めて使ったけど便利ですねぇ。)
persons画面イメージ.mov.gif

手順

以下のような手順で作成します。
が、死ぬほど長くなってしまったので、本記事は①②までとしました!!
③〜⑤は、後ほど作成します!カミングスーン!

①DynamoDBテーブルを作成する

1.1 テーブル作成
1.2 カラム作成

②GETメソッド作成(CRUDのR)

Lambda関数作成
API Gateway作成
Vue.js作成

③POSTメソッド作成(CRUDのC)

Lambda関数作成
API Gateway作成
Vue.js作成

④Deleteメソッドの作成(CRUDのD)

Lambda関数作成
API Gateway作成
Vue.js作成

⑤PUTメソッドの作成(CRUDのU)

前提条件

AWSアカウント作成ずみであること
(フルアクセス権限のIAMユーザを作ってそこから操作することをお勧めします。)

① DynamoDBテーブルを作成する

※ここからAWSマネジメントコンソール画面を操作していきますが、
今後、画面のレイアウト、表示項目などが変わる可能性があります!
本記事と、実際の画面が違った場合は、心で感じ取って、うまく進めてください!!

1.1 テーブル作成

AWSコンソールへログインし、DynamoDBの画面から「テーブル作成」を開く
DynamoDB Home

テーブル名(作ろうとしているアプリ名が良いですかね)とプライマリーキーを入力し、
「作成」を押下する
Create Table

1.2 カラム作成

画面左のメニューから「テーブル」をクリック
作成したテーブル名クリック
「項目」タブを開き
「項目の作成」をクリック
Create Columns

「+」をクリック、「Append」をクリック、「String」を選択
Create Columns 2

アプリに必要なカラム名を追加する。
add column name

同様の操作で必要なカラムを全て作成する。
add all columns

それぞれのカラムに適当なデータを入力します。(ドラえもんはPerson?? まぁいいやw)
put data

「保存」ボタンを押下します。
※データを入れてあげないと下のような赤文字のエラーが出ます。。。😂
save

これでDBは完成です。 ぅえーい!(・∀・)
DB Table Done

② GETメソッド作成(CRUDのR)

ここからCRUDごとに処理を作っていきます。

2.1 Lambda関数作成

AWSコンソールからlambda画面へ行き、「関数の作成」をクリックする
create lambda button

「一から作成」を選択(デフォルト)、
関数名を入力(今回はgetメソッドなので-getとする)
「Node.js」を選択(デフォルト)
「関数の作成」をクリックする
creating lambda

このような画面に遷移すればOKです。
lambda created

2.1.1 アクセス権限設定(IAMロール)

作成したlambda関数は現時点でDynamoDBにアクセスできません。(上記の作成手順の時に「アクセス権限」がノータッチだった為)
なので、先にそちらの設定をやっちゃいます。

作成したlambda関数画面から「アクセス権限」タブを開き、ロール名をクリックします。
このIAMロールはlambda関数作成時に自動で作られています。
lambda access setting

IAMロール画面が開き、「ポリシーをアタッチします」をクリック
attaching policy to role

検索窓に「dynamo」くらいで検査し、「AmazonDynamoDBFullAccess」を選択する
「ポリシーのアタッチ」をクリックする
attaching policy to role

以下メッセージが出れば、ロール設定完了です。
attaching policy to role

2.1.2 Lambda関数内にGet処理を書く

いよいよlambda関数にgetメソッドを書いていきます。

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

exports.handler = (event, context, callback) => {
    const httpMethod = event.httpMethod
    const params = {
        // ここで作成したDynamoDBテーブル名を指定
        'TableName': 'lambdaapp-persons'
    }
    dynamo.scan(params, function (err, data) {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data.Items)
        }
        callback(null, response)
    })
};

コードエディタの部分にコードを貼り付け、「Deploy」をクリックする
edit lambda code

2.1.3 Lambda関数をテストする

「テストイベントの選択」プルダウンより「テストイベントの設定」を選択
lambda test

任意のイベント名を入力し、「作成」をクリック
※Getメソッドではパラメータは特にないので、エディタの操作は不要
skip test settings

作成したテストイベントが選択された状態で「テスト」をクリック
test

うまくいくと「実行結果:成功」と表示されます。
test success

結果の詳細を見てみると、DynamoDBに登録したデータが取れているのが分かります。
test success

2.2 API Gateway作成

2.2.1 API Gateway作成

先ほど作成したGetメソッドをフロント側から呼び出せるようにAPI Gatewayを作成します。

API Gateway画面から「API 作成」をクリック
create api

API Typeを選択します。「REST API」の「構築」をクリック
select api type

「新しいAPI」(デフォルト)を選択、
API名を入力(1つのAPIでCRUD全て追加するので、ここではget、postなどは入れていません)、
「APIの作成」をクリック
api name etc

2.2.2 メソッドの作成

作成したAPI Gatewayの画面に遷移します。
「アクション」から「メソッドの作成」をクリック
action create method

プルダウンから「GET」を選択し、チェックマークをクリック
method type get

「GET - セットアップ」画面が現れます。
統合タイプ「lambda関数」を選択し、先ほど作成したlambda関数名を入力
「保存」をクリック
lambda name and save

下記メッセージはOKでOK。 ぇ?w
API to lambda trigger

Lambda関数を見てみると、上記「権限を与える」操作によりAPI Gatewayがトリガーとして追加されます。
lambda has trigger

2.2.3 メソッドをテスト

作成したAPI Gatewayメソッドからlambda関数が実行できるかテストします。

「テスト」をクリック
api gateway test

「テスト」をクリック!!
api gateway test

ボタンの下にテスト結果が表示されます。
ステータス:200であればOK。 bodyの所にDynamoDB作成時に作ったデータが入っていますね。
test result

2.2.4 CORSの有効化

説明しよう! CORSとは!
Cross-Origin Resource Sharing(オリジン間リソース共有)の略で
異なるオリジンとの通信ができるようにブラウザへ指示する仕組みだそうです。
今回の例で言うと、HTMLファイルをS3にアップロードして、S3から発行されたURLでブラウザに表示します。
さらにHTMLファイルの中にAPI GatewayのURLを書いて、メソッドを呼び出しています。
①S3のURLと②API GatewayのURLが異なるオリジンということになり、
それらを同時に扱うためにCORSが必要という事ですね。
参考

「アクション」から「CORSの有効化」をクリック
enable cors

GETメソッドに✅が入っていることを確認し、「CORSを有効にして既存のCORSヘッダーを置換」をクリック
enable cors

「はい、既存の値を置き換えます」をクリック
enable cors

全ての項目に✅が付き、エラーが出なければOK
enable cors

2.2.5 メソッドをデプロイ

「アクション」から「APIのデプロイ」をクリックします。
api deploy

デプロイされるステージはプルダウンから「新しいステージ」を選択
ステージ名に今回は「dev」と入力。※開発用だったらdev、商用だったらprodといった具合に分けるようですね
ステージの説明、デプロイメントの説明の入力は任意
「デプロイ」をクリック
set stage

デプロイが成功すると、APIのURLが表示されます。先ほど入力したステージ名が末尾に入っていますね。
set stage

2.3 Vue.js作成

2.3.1 ローカルでVue.jsを作成

まずはローカル環境にindex.htmlを作成し、vue.jsで書いていきます。
[作成したAPI GatewayのURL]の箇所をCtrl + Fで探して頂き、作成したAPIのURLを書きます。
ソースはGithubでも参照いただけます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Persons</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
  <div id="app">
    <div class="container mt-5">
      <div class="row">
        <div class="col-md-12">
          <h1>{{ title }}</h1>
          <h1>{{ psersons }}</h1>
          <p>Please add persons whom you like or respect, and describe them in detail.</p>
          <table class="table">
            <thead class="thead-dark">
              <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Description</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="person in persons">
                <td>{{ person.id }}</td>
                <td>{{ person.name }}</td>
                <td>{{ person.description }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    const vue = new Vue({
      el: "#app",
      data: {
        title: 'Persons',
        form: {
          id:'',
          name:'',
          description:''
        },
        persons: '',
        editIndex: -1,
        createFlag: true
      },
      mounted(){
        axios
          .get('[作成したAPI GatewayのURL]')
          .then(response => (this.persons = JSON.parse(response.data.body)))
          .catch(function(error){ 
            alert('Personsデータの取得に失敗しましたっ!\n(・Д・)ナンダッテェ!!' );
            console.log(error);
          });
      }
    });
  </script>
</body>
</html>

HTMLファイルをブラウザで実行すると以下のような画面が表示されます。
(ドラえもんだけだと寂しいので、もう1レコード追加してみました。てかPersonじゃないっすねwww)
ui

2.3.2 作成したVue.jsをS3へアップロード

まずS3バケットを作成します。
S3画面へ飛び、「バケットを作成」をクリック
create bucket

バケット名を入力します。下へスクロール。
create name

「パブリックアクセスを全てブロック」の✅を外し、下2つに✅をつける。
なかなか分かりづらいですが、要するにS3にあるHTMLファアイルをインターネットから参照できるようにしています。
さらに下へスクロール。
S3 access control

バケットのバージョニングは有効にすると、間違ってアップロードした時なんかに
元に戻せたりするみたいですね。お好みでどうぞ。
筆者はデフォルトの「無効」とします。
versioning

さらに下へスクロールし、「バケットを作成」を押下する。
create bucket

正常に作成されました、と言うメッセージが表示されます。
作成したS3バケットをクリック
create bucket success

下図のエリアにhtmlファイルをドラッグ&ドロップする
html drug drop

HTMLファイルが表示されます。下へスクロール
html appeard

「アップロード」をクリック
html appeard

アップロード成功しました。
html appeard

作成したバケットの画面に戻り、
アップロードしたHTMLファイルに✅をつけ、
「アクション」から「公開する」をクリック
koukai suru

「公開する」をクリック
koukai suru

正常に公開されました。とメッセージが表示されますね。
koukai suru

再びバケット画面に戻り、HTMLファイルをクリック
go to its url

「オブジェクト URL」をコピー
url

URLをブラウザで実行して、動作確認
(余談ですが、Qiita執筆中にChromeのアプデが来ましたね。右上の「更新」ってやつ)
url

終わりに

Qiitaを書いてみて

Qiitaを書くこと自体にめちゃめちゃ時間がかかってしまい、
Getメソッドのみになってしまいました!!
画面操作をここまで細かく説明する必要あるのか?という疑問も浮かびましたが、なるべく初学者目線で、をモットーに
そのまま描き続けました。
果たして分かりやすい記事になったのだろうか。。。!!

lambdaについて

今回はシンプルなアプリを作成しましたが、
きっともっと色んなことがlambdaを使ってできるはずなので、
(動画や画像など、様々なデータを扱ったりとか)
引き続き、何かを作りながら知見を深めていこうと思います!!

nakam-aws
AWSエンジニアです。 HTML/CSS/JavaScript/AWS/PHP/Laravel
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away