世界最大級のクラウドサービスとして有名なAWS。とても多機能で色々なことができますが、使いこなすには難易度が高いサービスでもあります。
スマートフォンアプリ開発をされている方の中には、バックエンド(サーバ)側の知識にあまり馴染みが無いという方も多いのではないでしょうか。そういった方におすすめしたいのが、AWS Mobile Hubです。AWSの中でもモバイルアプリ開発に利用できる機能をまとめて提供しているサービスになります。
本連載では、AWS Mobile Hubの各種機能をMonacaアプリに組み込む方法を紹介します。
今回紹介するのはその中に含まれるサービスの一つである、データベース機能です。
AWS Mobile HubのデータベースにはAmazon DynamoDBが使われています。内部的には、DynamoDBの操作を行うのはAWS Lambda経由、さらにそのLambda呼び出しはAPI Gateway経由となっており、複雑な構成で実現されています。
しかし、AWS Mobile Hubはそういった複雑な部分を意識せずに利用できるようになっています。
前提条件
この記事では、まずAWSのアカウントは持っていることとします。また、MonacaアプリはMonaca CLIを使ってローカルコンピュータ上で開発します。Monaca CLIを利用するのでNode.jsもインストールされていることとします。
インストール
AWS Mobile HubのCLIツールをインストールします。
$ npm install -g awsmobile-cli
Monacaアプリの作成
Monaca CLIを使ってアプリを作ります。テンプレートはなんでも構いませんが、ここでは「Onsen UI > Onsen UI V2 JS Minimum」を選択します。
$ monaca create AWSHubDemo_DB
プロジェクトのルートディレクトリに移動し、src
ディレクトリを作成しておいてください。
$ cd AWSHubDemo_DB
$ mkdir src
AWS Mobile Hubでプロジェクトを作る
AWS Mobile Hubのコンソールにサインインし、「Create Project」からウィザードに従ってプロジェクトを作成します。
プラットフォームは「Web」を選びます。
その際、「Enable web hosting with your app(ホスティングを有効にする)」のチェックは外しておきましょう。
ウィザードを進めるとコマンドが表示されますので、一番最後のコマンドをMonacaプロジェクトのルートディレクトリで実行します。
$ awsmobile init xxxxxxxxxxxx
実行すると、初期設定項目の入力を求められますが、すべてデフォルトのままEnterを押していきます。
すると、以下のようにキーの入力がが求められます。
Please enter the access key of the newly created user:
? accessKeyId: (<YOUR_ACCESS_KEY_ID>)
Enterを押すとブラウザで AWS IAM のページが開くので、「プログラムによるアクセス」にチェックが入った状態で次に進みます。
AdministratorAccess
権限を割り当てて次へ進みます。
完了画面に表示される「アクセスキーID」と「シークレットアクセスキー」をコマンドラインから入力してください。
Please enter the access key of the newly created user:
? accessKeyId: xxxxxxxxxxx
? secretAccessKey: xxxxxxxxxxxxxxxxxxxxxxxxxxx
srcディレクトリ内に aws-exports.js
というファイルができていれば完了です。
データベース設定
データベース設定はCLIで行います。まずはデータベースを有効化します。
$ awsmobile database enable --prompt
アクセス権限を設定します。今回はOpenとしています。
? Should the data of this table be open or restricted by user?
❯ Open
Restricted
テーブル名を入力します。
? Table name: todos
次にカラムを設定します。カラム名は「team」、データタイプは「string」を指定します。
? What would you like to name this column: team
? Choose the data type: string
さらに他のカラムを追加するか聞かれるので、Yes と答えて todoId(数字)、text(string)の2つを追加します。
? Would you like to add another column: Yes
? What would you like to name this column: todoId
? Choose the data type: number
? Would you like to add another column: Yes
? What would you like to name this column: text
? Choose the data type: string
? Would you like to add another column: No
プライマリキーを聞かれますのでteamを選択します。このプライマリキーはユニークであると言うよりも、情報をフィルタリングするためのキーになります。team単位でタスクを管理するようなイメージです。
? Select primary key
❯ team
todoId
text
後はソートキーとしてtodoIdを指定、インデックスを追加するかどうかの質問にはNoと回答して完了です。
? Select sort key
❯ todoId
text
(No Sort Key)
? Add index (Y/n): n
Table todos saved.
CRUD APIの追加
次に作成したテーブルに対してCRUD操作を行うAPIを追加します。
$ awsmobile cloud-api enable --prompt
APIをどう作成するか選びます。これは「Create CRUD API for an existing Amazon DynamoDB table(既存のDynamoDBのテーブル)」を選んでください。
? Select from one of the choices below. (Use arrow keys)
Create a new API
❯ Create CRUD API for an existing Amazon DynamoDB table
そうするとDynamoDBのテーブルが一覧に並びますので、そこから先程作成した「todos」を選びます。
? Select Amazon DynamoDB table to connect to a CRUD API
❯ todos
完了したら、最後にpushします。
$ awsmobile push
これでLambdaに関数が作られ、それを操作するAPI Gatewayのエンドポイントが作られます。以下は awsmobile push
を実行した際に表示されるログです。
$ awsmobile push
checking the backend contents
building cloud-api
zipping todos
done
generating backend project content
done
backend build artifacts are saved at:
/path/to/monaca-project/awsmobilejs/.awsmobile/backend-build
preparing for backend project update: MonacaDB
uploading todos-20180815100255.zip
upload Successful todos-20180815100255.zip
done
updating backend project: MonacaDB
awsmobile api call successful
waiting for the cloud formation to complete
cloud-api update finished with status code: CREATE_COMPLETE
Successfully updated the backend awsmobile project: MonacaDB
retrieving the latest backend awsmobile project information
awsmobile project's details logged at:
awsmobilejs/#current-backend-info/backend-details.json
awsmobile project's specifications logged at:
awsmobilejs/#current-backend-info/mobile-hub-project.yml
awsmobile project's access information logged at:
awsmobilejs/#current-backend-info/aws-exports.js
awsmobile project's access information copied to:
src/aws-exports.js
contents in #current-backend-info/ is synchronized with the latest in the aws cloud
JavaScriptの実装と変換
gulpを使ってソースの変換を行いますので、npm install
コマンドで以下のライブラリをインストールしてください。
- gulp
- browserify
- babelify
- babel-register
- babel-preset-es2015
- vinyl-source-stream
src/index.js
を作成し、AWSのJavaScriptライブラリ aws-amplify
から利用したい機能を取り出します。データベース機能を利用するには「API」モジュールが必要です。
src/index.js
import Amplify, { API } from 'aws-amplify';
import awsmobile from './aws-exports.js';
Amplify.configure(awsmobile);
window.API = API;
このファイルのままではMonacaから使えないので、ソースを変換します。今回はgulpを使います。プロジェクトのルートディレクトリ以下に gulpfile.babel.js
を作成します。
gulpfile.babel.js
import gulp from 'gulp';
import browserify from "browserify";
import babelify from "babelify";
import source from "vinyl-source-stream";
gulp.task("default", () => {
browserify({
entries: ["./src/index.js"]
})
.transform(babelify, {presets: ['es2015']})
.bundle()
.pipe(source("app.js"))
.pipe(gulp.dest("www/js"));
});
gulp.task('watch', function(){
gulp.watch('./src/*.js', ['default']);
});
さらに .babelrc
を作成します。これでES2015の構文が使えます。
.babelrc
{
"presets": ["es2015"]
}
最後に package.json
に以下のコマンドを追加します。
"scripts": {
"watch": "node node_modules/gulp/bin/gulp.js watch"
},
これで準備完了です。 npm run watch
を実行すると、 src/index.js
の内容をコンパイルして www/js/app.js
として書き出します。
こうして書き出されたファイルを、www/index.html
内に読み込みます。
<script src="js/app.js"></script>
JavaScriptの実装
全体のコードはこちらにアップロードされています。
database.html
にデータベース接続処理が実装されています。
データの一覧を取得
データの取得は API.get()
で実行します。第一引数には「テーブル名 + CRUD」という名前を指定します。結果としてテーブルのデータが配列形式で返ってきます。
const updateTodo = async () => {
const todos = await API.get('todosCRUD', `/todos/${team}`)
Todo = todos;
const html = [];
for (todo of Todo) {
html.push(`<ons-list-item>${todo.text} <div onclick="deleteTodo('${todo.todoId}')"> (削除)</div></ons-list-item>`);
}
me.querySelector('.todos').innerHTML = html.join("");
}
データの登録
データの登録は API.post()
を使います。bodyパラメータに登録内容を指定します。
この時のレスポンスは登録が成功したというメッセージのみになります。そのため、登録したデータを表示するためには再度データ一覧を取得する必要があります。
const postTodo = async (text) => {
return await API.post('todosCRUD', '/todos', {
body: {
todoId: Todo.length + 1,
text: text,
team: team
}
})
};
データの更新も同じフォーマットで、メソッドが API.put()
に変わるだけです。
データの削除
データの削除は API.del()
メソッドになります。また、第二引数に指定するURLが若干変わって、 /object/ というパスが入ります。
const deleteTodo = async (todoId) => {
await API.del('todosCRUD', `/todos/object/${team}/${todoId}`)
updateTodo();
}
AWSのクラウドデータベースは様々なサービスが組み合わさって提供されていますが、AWS Mobile Hubからであれば裏側の複雑さを気にすることなく使えます。NoSQL型なのでAPIを叩くだけで容易にCRUD処理を行えるのが魅力といえるでしょう。
今回のコードはgoofmint/Monaca_AWSHub_Databaseにアップロードしてあります。実装時の参考にしてください。