AWS Amplify のサンドボックスを試してみた


こんにちは。いよいよGWですね。今年は何をして過ごしましょうか?私は娘と一緒に狩(モンハン)に出かける予定でいっぱいです!今から楽しみで仕方がありません!!

さて、今回はAWS Amplifyのサンドボックスを試してみたので、利用方法と感想を書きたいと思います。

AWS Amplifyについてはこちらをご確認ください。
AWS Amplify(アプリケーションの構築とデプロイ)| AWS

Admin UI についてはこちらをご確認ください。
新機能 – AWS Amplify Admin UI: アプリケーションのバックエンド開発を支援し、クラウドの経験を必要としない管理ツール | Amazon Web Services ブログ

AWS Amplify のサンドボックスを準備する

まずは以下のURLにアクセスして、サンドボックス環境を作ります。
https://sandbox.amplifyapp.com/start

「Pick a feature to set up」は「Data」を選択。 「Build a data model in the sandbox」は「To-do list schema」を選択し、「create new schema」をクリックして登録します。

次のData modelingについては、今回はデータ構造はそのまま使いますので、そのまま進めます。「Next: Test locally in your app」をクリックします。

これでサンドボックス環境の出来上がりです。

ローカル環境の設定

画面の指示にしたがって、ローカルの環境を構築していきます。

① What type of app are you building?

platform は Web、Framework/Language は React を選択します。

② (Optional) Create a new app

以下のコマンドを実行して、reactのアプリケーションのベースを作成します。

npx create-react-app react-amplified
cd react-amplified

③ Install Amplify CLI to pull the data model

amplify cli がインストールされていない場合はこちらも実行します。 (インストール済の場合はスキップ)

curl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL

amplifyコマンドが利用できるようになったら、sandboxの環境を手元にダウンロードします。

amplify pull --sandboxId xxxxxx
# 注意)xxxxxxの部分は変わりますので、画面に表示されるコードを使用してください。

④ Install Amplify library and initialize Amplify

画面表示に従い、必要ライブラリーのインストールをおこないます。

npm install aws-amplify typescript

create-react-app で作成された index.js に以下のコードを追加します。(Amplifyのライブラリと設定ファイルを読み込む処理)

import Amplify from 'aws-amplify'
import awsconfig from './aws-exports'

Amplify.configure(awsconfig)

⑤ Test CRUD APIs locally with Amplify DataStore

こちらではcreate, update, delete, query(read)のそれぞれの書き方が確認できますので、そちらも確認してみましょう。

アプリを動かしてみる

以上、アプリの開発環境が整いましたので、実際にアプリケーションを動かしてみたいと思います。 App.jsを以下のファイルに置き換えます。

import { useEffect, useState } from 'react'
import { DataStore } from '@aws-amplify/datastore';
import { Todo } from './models';

const App = () => {
  // 新規登録用にreact hooksを利用して入れ物を準備します。
  const [todoName, setTodoName] = useState('')
  const [todoDesc, setTodoDesc] = useState('')
  // 新規登録時のバリデーション用(簡易版)にtodoNameが空の状態を検知させます。
  const unCreatable = todoName === ''

  // todo の一覧の入れ物を作成。デフォルトでArrayになるようにする。
  const [todoList, setTodoList] = useState([])

  // TODO 新規登録
  const createTodo = async (values) => {
    // 以下のAPIの処理はブラウザに表示されていたサンプルコードを利用しています。
    const response = await DataStore.save(
      new Todo(values)
    );
    console.log('新規登録結果', response)

    // 新規登録されたTODOをtodoListへ追加します。(配列を作り直す必要があります。)
    setTodoList([...todoList, response])
  }

  // TODO 削除
  const deleteTodo = async (id) => {
    // APIの処理はブラウザに表示されていたサンプルコードを利用しています。
    const modelToDelete = await DataStore.query(Todo, id);
    const response = await DataStore.delete(modelToDelete);
    console.log('削除結果', response)

    // 削除されたTODOをtodoListから取り除きます。(配列を作り直す必要があります。)
    setTodoList(
      todoList.filter(todo => todo.id !== response.id)
    )
  }

  // TODO 読み込み
  const readTodo = async () => {
    // APIの処理はブラウザに表示されていたサンプルコードを利用しています。
    const models = await DataStore.query(Todo);

    console.log('一覧取得結果', models);
    setTodoList(models)
  }

  // コンポーネントのマウント時に実行される処理
  useEffect( () => {
    readTodo()
  }, [])

  // 新規登録呼び出し
  const handleClickCreateTodo = () => {
    const values = {
      name: todoName,
      description: todoDesc,
    }
    createTodo(values)

    // 登録が完了したらフォームの値を空に設定します。
    setTodoName('')
    setTodoDesc('')
  }

  // 削除呼び出し
  const handleClickDeleteTodo = (id) => {
    deleteTodo(id)
  }

  return (
    <div style={{padding: 40}}>

      <h2>Todo list</h2>
      <ul>
      {
        todoList.map((todo, index) => {
          return (
            <li key={index} style={{marginBottom: 15}}>
              <div>Name: {todo.name}</div>
              <div>Description: {todo.description}</div>
              <div><button onClick={() => handleClickDeleteTodo(todo.id) } >削除</button></div>
            </li>
          )
        })
      }
      </ul>

      <h2>Add todo</h2>
      <div>
        <label>Name: <input value={todoName} onChange={ e => setTodoName(e.target.value)} /></label><br />
        <label>Discription: <input value={todoDesc} onChange={ e => setTodoDesc(e.target.value)} /></label><br />
        <button onClick={handleClickCreateTodo} disabled={unCreatable}>追加する</button>
      </div>

    </div>
  )
}

export default App;

あとは npm start でアプリケーションを起動しTodoの追加と削除を試してみてください。 下記のように動いていれば完成です。 何をしているかは簡単ですが、コード内にコメントを書いているので興味のある人はそちらをご確認ください。

感想

とりあえず、アプリっぽいものが動くことが確認できたかと思います。このようにAmplifyサンドボックスはAWSのアカウントなしでもAmplifyの機能の一部を気軽に試すことができるのは非常に便利なツールです。

サンドボックスを使えるようになったことで、今回の作業ではバックエンドの設定は5〜10分程度で終わり、アプリケーションの開発に大部分の時間を使いました。(バックエンドの設定とアプリケーションの開発を合わせても1時間〜1時間くらいでサクッと動くものが作成できました。)

AWS Amplifyはまだまだ発展途上の印象を受けることもありますが、サーバーレスアプリケーションを構築上でかなり便利なツールだと思います。今後も積極的に活用していきたいと思います!!

余談
実はこのサンドボックスから作成したアプリをそのままデプロイすることもできるようだったので、試してみたのですが、なぜかうまくデプロイできず。。(AWS上にAmpliffyのアプリを作る過程でAPIの設定が消えてしまって。。) 何か自分の作業に問題があったのかなと思いつつ、原因はわからず。今回は時間の都合で再度試すことはできなかったので、また時間のある時に試してみたいと思います!

こちらの記事もオススメです!
Webサイトのデプロイ作業をAWS Amplifyに移行しています
WebサイトへのデプロイをAmplifyに移行。設定ミスを防ぐためCloudFormationを活用しています。
オンラインツアーをはじめて体験してみました
オンラインツアーでは、簡単に行くことができない地域のツアーに気軽に参加できます。
TourBoxを使って動画編集処理の時間短縮に成功!
ダイヤルやボタンにキーボードショートカットを自由に定義。Premiere Proでの動画編集作業がとても楽になりました。
紙の書籍から電子書籍での読書に変えました
KindleとFire HDを使い分けて電子書籍を読んでいます。
AWSクラウドハンズオン講座で講師デビューしました(動画・資料あり)
AWSのハンズオン講座で初めて講師を務めました。動画や資料もあります。
ファーエンドテクノロジーからのお知らせ(2021/04/28更新)
Redmine 4.2.0以前のGitアダプタの任意ファイル読み取り脆弱性 (#35085) 対応済みのご報告
Redmine 4.2.0以前のGitアダプタの任意ファイル読み取り脆弱性 (#35085) 対応済みのご報告
2021年度ブランドパートナーに島根県在住のモデル ユイさんを連続起用
ユイさん(モデルスタジオミューズ所属)をファーエンドテクノロジーのブランドパートナーとして継続して起用します。今年度で4年目となります。
My Redmine TLS 1.0 / 1.1 無効化のお知らせ
Redmineのクラウドサービス「My Redmine」では、古い暗号化通信プロトコルであるTLS 1.0と1.1を無効化しました。
APPS JAPAN 2021 フェーズ02(4/19〜23開催)にオンライン出展
4月19日〜23日に開催される「APPS JAPAN 2021」のフェーズ02(オンライン開催)に出展します。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け