ほぼPythonだけでサーバーレスアプリをつくろう をやってみた(5章)後編

IT

Webアプリの顔、フロントエンドを作る章、長いので2つに分けた後編です。

mosoメモ
mosoメモ

データ取り扱いの3種の神器(アクション)、
登録、変更、削除を押さえておこう。
AWSへのデプロイもやるよ。

ほぼPythonだけでサーバーレスアプリをつくろう

Amazon

第5章 Transcryptで画面の実装をしよう(後編)

第4章までにバックエンドのWeb APIが完成したので、今回はフロントエンドの実装を行うという内容です。
後編は、新規・変更・削除の機能AWSへのデプロイを行います。

第5章(後編)で実際に行った内容詳細

新規登録機能を実装する

Model、View、Presenterにそれぞれ新規登録機能のためのコードを追加します。

Modelクラス(model.py)の修正

Modelクラスを修正します。

model.pyにコードを追加します。

≪略≫

    # ① ToDo登録のAPIを呼び出す
    def create_todo(self, data):
        S.ajax({
            'url': f"{BASE_URL}todos",
            'type': 'POST',
            'contentType': 'application/json',
            'data': JSON.stringify(data),
        }).done(
            self._success_create_todo
        ).fail(
            lambda d: alert('サーバーとの通信に失敗しました。')
        )
    
    # ② create_todo() 成功時の処理
    def _success_create_todo(self, data):
        self._todos.append(data)
        S('body').trigger('todos-updated')

ToDo登録するためのメソッドを追加しています。

  • create_todo()

    Todo登録のAPI(つまり、バックエンドを動かすURL)を呼び出すメソッド、Ajax使ってます。成功すれば↓のメソッドを呼びます。
  • _success_create_todo()

    表示を更新するメソッドです。
    バックエンドのデータを更新した後、画面表示を更新します。

Viewクラス(view.py)の修正

Viewクラスを修正します。

view.pyにコードを追加します。

≪略≫

    # ① 新規登録のモーダルダイアログを表示する
    def show_new_modal(self):
        S('#modal-title').text('新規登録')
        S('#modal-todo-id').val('')
        S('#modal-todo-title').val('')
        S('#modal-todo-memo').val('')
        S('#modal-todo-priority').val('1')

    # ② モーダルダイアログを閉じる
    def close_modal(self):
        S('#input-form').modal('hide')
    
    # ③ モーダルダイアログの入力内容を取得する
    def get_input_data(self):
        return {
            'id': S('#modal-todo-id').val(),
            'title': S('#modal-todo-title').val(),
            'memo': S('#modal-todo-memo').val(),
            'priority': S('#modal-todo-priority').val(),
        }

3つのメソッドを追加しています。

  • show_new_modal()

    新規にToDoを入力するための画面を表示するメソッド
  • close_modal()

    入力画面を閉じるメソッド
  • get_input_data()

    入力内容を取得するメソッド

Presenterクラス(presenter.py)の修正

Presenterクラスを修正します。

presenter.pyにコードを追加します。

≪略≫

    # イベントをバインドする
    def _bind(self):
        S('body').on('todos-updated', self._on_todos_updated)
        S('#input-form').on('show.bs.modal', self._on_sohw_modal)
        S('#register-button').on('click', self._on_click_register)

≪略≫

    # show.bs.modal受信時の処理
    def _on_sohw_modal(self, event):
        self._view.show_new_modal()
    
    # register-buttonのクリック受信時の処理
    def _on_click_register(self, event):
        input_data = self._view.get_input_data()
        self._model.create_todo(input_data)
        self._view.close_modal()

イベントバインドを2つ追加とそれに対応するメソッドを2つ追加しています。

  • _bind() 内の $(‘#input-form’)

    show.bs.modalイベント受信時の処理を追加。

    このイベントを受信すると、_on_sohw_modal()メソッドを呼び出します。
    ※show.bs.modalイベントはBootstrapで定義されたイベントで、モーダルダイアログが表示されるまでに発生するものです。

    つまり、[新規登録]ボタンが押された時に_on_show_modal()メソッドを呼び出します。
  • _bind() 内の$(‘#register-button’)

    clickイベント受信時の処理を追加。

    このイベントを受信すると、_on_click_register()メソッドを呼び出します。
  • _on_show_modal()

    Viewクラスの show_new_modal()メソッドを呼び出します。

    つまり、新規ToDo入力用モーダル画面を表示します。
  • _on_click_register()

    View経由で入力データを取得し、Model経由でデータを登録、そして最後にToDo入力用モーダル画面をとじます。

PythonコードをTranscryptでJavaScriptに変換する

フロントエンド環境を実行した状態で以下コードを実行します。
エラーがでなければ、JavaScriptファイルができます。

第5章(前編)でやったのと同じTranscryptコードでOKです。

(hobopy-frontend) C:\Users\Moso\hobopy\hobopy-frontend>transcrypt -b hobopy-frontend

動作を確認する

ローカルデータベース、バックエンドAPI、Web Server for Chromeを起動して動作を確認します。

ToDoアプリの新規登録機能が
実装できました。

変更、削除の機能を実装する

これら機能も流れは新規機能の実装と同様であり、Model、View、Presenterにコードを追加して、TranscryptでJavaScriptに変換して動作確認をしました。

流れは新規と同様のため割愛。
コードは、作者さんのGithubに公開されていますので見てください。

GitHub - 7pairs/hobopy: ほぼPythonだけでサーバーレスアプリをつくろう
ほぼPythonだけでサーバーレスアプリをつくろう. Contribute to 7pairs/hobopy development by creating an account on GitHub.

AWSにデプロイする

バックエンドのデプロイ

まずは、CORS対応をしたバックエンドをデプロイしましょう。
バックエンド環境を起動して、以下コマンドを実行します。(4章の内容です)

(hobopy-backend) C:\Users\Moso\hobopy\hobopy-backend>chalice deploy --stage prod
Creating deployment package.
Updating policy for IAM role: hobopy-backend-prod-api_handler
Updating lambda function: hobopy-backend-prod
Updating rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:xxxxx:function:hobopy-backend-prod
  - Rest API URL: https://xxx.execute-api.ap-northeast-1.amazonaws.com/api/

フロントエンドのデプロイ先の準備

AWSにフロントエンドを実装するには、S3というサービスを使います。
ここに、HTMLやJavaScriptファイルを置きます。

Simple Storage Service の頭文字をとって S3らしい。
バケット作成

S3サービス上にファイルを置く場所をバケットというらしいです。
そのバケットをまず作ります。以下コマンドを実行することで作れます。

> aws s3 mb s3://moso-hobopy-frontend
make_bucket: moso-hobopy-frontend

ちなみに、バケット名はリージョン内でユニークでないといけないらしく、本に書かれていたバケット名(hobopy-frontend)はエラーが出ました。

AWSのS3サービス上にバケットができました。

Static Website Hostingを有効にする

本では細かい説明はなかったですが、バケット内に httpでのアクセスポイントを作れる感じですかね。

以下コマンドを実行します。

> aws s3 website s3://moso-hobopy-frontend --index-document index.html

moso-hobopy-frontendバケットの Static website hostingが有効になりました。

外部からアクセスできるようバケットのポリシーを変更する

ポリシー用のJSONファイルを作成してコマンドで反映します。

以下のjsonファイルを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::moso-hobopy-frontend/*"
        }
    ]
}

そして、以下コマンドを実行します。

C:\Users\Moso\hobopy\hobopy-frontend>aws s3api put-bucket-policy --bucket moso-hobopy-frontend --policy file://bucket-policy.json

バケットポリシーができました。

これでフロントエンドファイルのアップロード先が準備できました。

フロントエンドのデプロイ

ローカルに作ったのフロントエンドファイルをアップロードする前に、ベースURLを指定するファイル(const.py)を修正しましょう。

BASE_URL = 'https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/api/'

プログラムを修正したら、もちろん JavaScriptを再作成します。

(hobopy-frontend) C:\Users\Moso\hobopy\hobopy-frontend>transcrypt -b hobopy-frontend

デプロイ用のフォルダ deployを作ってその中に、index.htmlとJavaScriptファイルを配置します。

最後にアップロードコマンドを実行してデプロイ完了です。

C:\Users\Moso\hobopy\hobopy-frontend>aws s3 sync deploy s3://moso-hobopy-frontend

AWS S3のバケット内にファイルアップロードができました。

AWSにデプロイしたアプリの動作確認

通常のWebブラウザからデプロイしたアプリのURLにアクセスします。

アプリが動きました!

当章は以上ですが、ログインなどセキュリティ設定を組み込んでいないので、せっかくですがパブリックアクセス権をはく奪して終了です。

先ほど作ったバケットポリシーを削除すれば、アクセスはできなくなります。

第5章(後編)の所要時間

約4時間かかりました。

行った内容はそれほど難しくないはずですが、単純にコードを書く量が増えたことと、AWSへのデプロイ(内容の理解)もあり時間がかかりました。

このくらいかかるのは想定内です。

第5章(後編)のつまづきポイント

まず1つ目が、第1~4章で行った内容を覚えていること前提で進みます。
取組みに間があけば、内容を忘れてしまうので思い出すために時間がかかりました。

もう1つが、ToDoアプリを登録するモーダル画面のプログラムです。
modelとmodalが似ていて書き間違いが多発しました。ここ間違うだけで画面が何も動きません、エラーも出ません。気づくのに少し時間がかかりました。

第4章(データベースアクセス)に比べたらつまづきポイントは少ないと思います。

第5章(後編)の感想

時間があるGW中に取り組んだ第4章と違い、第5章は細切れな時間での作業であったため、作業効率は悪かったと思います。
プログラミングに取り組むには、まとまった時間があったほうが絶対に良いです。

しかし、AWSにデプロイしてアプリが動いた時は感動しますね!
ToDoアプリを作れたのは良い体験だと思います。
 ※作者さんのプログラミングだけどね…
 ※ログイン認証なしで登録ができちゃうけどね…

今回行った一連の流れが、Webアプリの一つの実装方法だと思いますが、他にも色々ありそう。多くの実装パターンに触れることが成長に繋がるのではと思います。

 …嗚呼、時間がほしい。

コメント

タイトルとURLをコピーしました