記事を閲覧いただき、ありがとうございます。中村です!!
2020年10月にAWSエンジニアとして転職したので、AWSの予習も兼ねてLambdaを使ったアプリ作成について書いきます。
AWS Lambdaとは?
ここでつらつら説明するより公式動画の方がわかりやすいという結論に至りました。まずはご覧ください。
以下を使用して作成ます。
フロントエンド : Vue.js
AWS(インフラ) : S3, API Gateway, Lambda, DynamoDB
構成
構成はこんな感じです。
DBはDynamoDB、アプリケーションサーバの代わりにlambdaを使ってサーバレスにする。
lambdaプログラムをAPI Gatewayと連携し、APIとして呼べるようにする。
Webサーバのように使えるS3にフロントエンドのプログラムをデプロイする。
画面
画面こんな感じです。
めちゃシンプルですが、自分の尊敬する人/好きな有名人などの情報を記録するアプリを作ります。
(余談: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の画面から「テーブル作成」を開く
テーブル名(作ろうとしているアプリ名が良いですかね)とプライマリーキーを入力し、
「作成」を押下する
1.2 カラム作成
画面左のメニューから「テーブル」をクリック
作成したテーブル名クリック
「項目」タブを開き
「項目の作成」をクリック
「+」をクリック、「Append」をクリック、「String」を選択
それぞれのカラムに適当なデータを入力します。(ドラえもんはPerson?? まぁいいやw)
「保存」ボタンを押下します。
※データを入れてあげないと下のような赤文字のエラーが出ます。。。😂
② GETメソッド作成(CRUDのR)
ここからCRUDごとに処理を作っていきます。
2.1 Lambda関数作成
AWSコンソールからlambda画面へ行き、「関数の作成」をクリックする
「一から作成」を選択(デフォルト)、
関数名を入力(今回はgetメソッドなので-get
とする)
「Node.js」を選択(デフォルト)
「関数の作成」をクリックする
2.1.1 アクセス権限設定(IAMロール)
作成したlambda関数は現時点でDynamoDBにアクセスできません。(上記の作成手順の時に「アクセス権限」がノータッチだった為)
なので、先にそちらの設定をやっちゃいます。
作成したlambda関数画面から「アクセス権限」タブを開き、ロール名をクリックします。
このIAMロールはlambda関数作成時に自動で作られています。
IAMロール画面が開き、「ポリシーをアタッチします」をクリック
検索窓に「dynamo」くらいで検査し、「AmazonDynamoDBFullAccess」を選択する
「ポリシーのアタッチ」をクリックする
2.1.2 Lambda関数内にGet処理を書く
いよいよlambda関数にgetメソッドを書いていきます。
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」をクリックする
2.1.3 Lambda関数をテストする
「テストイベントの選択」プルダウンより「テストイベントの設定」を選択
任意のイベント名を入力し、「作成」をクリック
※Getメソッドではパラメータは特にないので、エディタの操作は不要
作成したテストイベントが選択された状態で「テスト」をクリック
結果の詳細を見てみると、DynamoDBに登録したデータが取れているのが分かります。
2.2 API Gateway作成
2.2.1 API Gateway作成
先ほど作成したGetメソッドをフロント側から呼び出せるようにAPI Gatewayを作成します。
API Typeを選択します。「REST API」の「構築」をクリック
「新しいAPI」(デフォルト)を選択、
API名を入力(1つのAPIでCRUD全て追加するので、ここではget、postなどは入れていません)、
「APIの作成」をクリック
2.2.2 メソッドの作成
作成したAPI Gatewayの画面に遷移します。
「アクション」から「メソッドの作成」をクリック
「GET - セットアップ」画面が現れます。
統合タイプ「lambda関数」を選択し、先ほど作成したlambda関数名を入力
「保存」をクリック
Lambda関数を見てみると、上記「権限を与える」操作によりAPI Gatewayがトリガーとして追加されます。
2.2.3 メソッドをテスト
作成したAPI Gatewayメソッドからlambda関数が実行できるかテストします。
ボタンの下にテスト結果が表示されます。
ステータス:200であればOK。 bodyの所にDynamoDB作成時に作ったデータが入っていますね。
2.2.4 CORSの有効化
説明しよう! CORSとは!
Cross-Origin Resource Sharing(オリジン間リソース共有)の略で
異なるオリジンとの通信ができるようにブラウザへ指示する仕組みだそうです。
今回の例で言うと、HTMLファイルをS3にアップロードして、S3から発行されたURLでブラウザに表示します。
さらにHTMLファイルの中にAPI GatewayのURLを書いて、メソッドを呼び出しています。
①S3のURLと②API GatewayのURLが異なるオリジンということになり、
それらを同時に扱うためにCORSが必要という事ですね。
参考
GETメソッドに✅が入っていることを確認し、「CORSを有効にして既存のCORSヘッダーを置換」をクリック
2.2.5 メソッドをデプロイ
デプロイされるステージはプルダウンから「新しいステージ」を選択
ステージ名に今回は「dev」と入力。※開発用だったらdev、商用だったらprodといった具合に分けるようですね
ステージの説明、デプロイメントの説明の入力は任意
「デプロイ」をクリック
デプロイが成功すると、APIのURLが表示されます。先ほど入力したステージ名が末尾に入っていますね。
2.3 Vue.js作成
2.3.1 ローカルでVue.jsを作成
まずはローカル環境にindex.htmlを作成し、vue.jsで書いていきます。
[作成したAPI GatewayのURL]
の箇所をCtrl + F
で探して頂き、作成したAPIのURLを書きます。
ソースはGithubでも参照いただけます。
<!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)
2.3.2 作成したVue.jsをS3へアップロード
まずS3バケットを作成します。
S3画面へ飛び、「バケットを作成」をクリック
「パブリックアクセスを全てブロック」の✅を外し、下2つに✅をつける。
なかなか分かりづらいですが、要するにS3にあるHTMLファアイルをインターネットから参照できるようにしています。
さらに下へスクロール。
バケットのバージョニングは有効にすると、間違ってアップロードした時なんかに
元に戻せたりするみたいですね。お好みでどうぞ。
筆者はデフォルトの「無効」とします。
正常に作成されました、と言うメッセージが表示されます。
作成したS3バケットをクリック
作成したバケットの画面に戻り、
アップロードしたHTMLファイルに✅をつけ、
「アクション」から「公開する」をクリック
URLをブラウザで実行して、動作確認
(余談ですが、Qiita執筆中にChromeのアプデが来ましたね。右上の「更新」ってやつ)
終わりに
Qiitaを書いてみて
Qiitaを書くこと自体にめちゃめちゃ時間がかかってしまい、
Getメソッドのみになってしまいました!!
画面操作をここまで細かく説明する必要あるのか?という疑問も浮かびましたが、なるべく初学者目線で、をモットーに
そのまま描き続けました。
果たして分かりやすい記事になったのだろうか。。。!!
lambdaについて
今回はシンプルなアプリを作成しましたが、
きっともっと色んなことがlambdaを使ってできるはずなので、
(動画や画像など、様々なデータを扱ったりとか)
引き続き、何かを作りながら知見を深めていこうと思います!!