サーバレスシングルページアプリケーションについて
サーバーレスシングルページアプリケーション ―S3、AWS Lambda、API Gateway、DynamoDB、Cognitoで構築するスケーラブルなWebサービス
- 作者: Ben Rady,吉田真吾,笹井崇司
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/06/23
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
この本を読んで、学んだことや思ったことをまとめてみた。
SPAとは?
SPA(SinglePageApplication)とは、ユーザから見て、Webページ全体をサーバから取得するような更新を行うことなく、部分的な更新をクライアントサイドで行うことで動的コンテンツを提供するWebアプリケーションのこと。
従来のWebアプリはサーバサイドでHTMLを生成してクライアントサイドに送信するのが基本だが、SPAではページの一部のデータのみについて最新の状態を取得し、ページを部分的に書き換えるのが基本となる。
これにより、ネイティブアプリに近い使用感をWebアプリで提供できる。
SPAの要素
SPAを開発するにあたっての基本要素は以下の通り。
コンポーネント
まとまった機能を提供する単位にまとめたビューを作ると、画面の部分的な更新や差し替えの見通しが良くなる。このまとまった単位をコンポーネントと言う。
HTMLだけでなく、後述のカスタムイベント、およびCSSまで含むことがあるが、どこまでを含めるかはフレームワークや設計によりけり。
ルーティング
SPAにおいては画面の切り替えはビューコンポーネントの差し替えであり、クライアントサイドで処理することになる。
画面切り替えだけなら単純であるが、ユーザエクスペリエンスを考慮すると、URLとページの状態を紐付けたり、ブラウザの戻るボタンを有効に機能させるためにhistory APIを活用したりする必要がある。
書籍で紹介されていた実装パターン
書き換え先のページはURLで示すが、サーバへリクエストを送らない単一ページ内のリンクとして動作させるために、ハッシュURLを使う。
ハッシュURLに対応するHTML構造をテンプレートとして保持しておき、要求されたURLに応じたテンプレートからDOMを構築し、現在のHTMLツリーの書き換え対象エレメントの中身を入れ替える。
データバインディング
バックエンドのAPIから得たデータを使ってページを部分更新する際、毎度ページ全体を再構築すると通常のアプリと変わらなくなってしまう。また、データが書き換わったときに改めてDOM操作をするのは、あらゆる状態に対して「変更」操作を記述する必要があり、複雑な状態遷移を持つ場合に課題があった。
そこで、「唯一信じられるデータソース」を持ち、書き換えたい対象のエレメントにデータを紐付けておき、データソースが書き換わったら対応するビューも書き換える(ことを裏で自動で行う)仕組みが発明され、これをデータバインディングという。
データバインディングには単方向と双方向があり、データソース→ビュー方向の同期のみ行うのが単方向データバインディング、ビュー→データソース方向の同期も行うのが双方向データバインディング。
単方向は読み取り専用データ、双方向はフォームなどの編集可能データに使われる。
カスタムイベント
ビューをコンポーネントとして管理すると、コンポーネントというまとまった単位として扱うイベントを定義したくなる。これをカスタムイベントと言う。
書籍で紹介されていた実装パターン
jQueryではbind関数とtrigger関数を使うことで任意のイベントを登録・発火できる。
これを利用して、あるビューがロードされたときにbindでカスタムイベントを登録し、他からtriggerで発火することで、ビューに対する独自イベントを作れる。
SPAフレームワーク
フレームワークは上記のような要素を実装する手助けをしてくれる。それに加え、以下のような特徴を持つ。
リアクティブ
=宣言的。DOMエレメントをあれこれいじって形を変えてビューを作るのではなく、「このデータならこのビュー」というあるべき姿を宣言しておき、データを変更すると裏で宣言したとおりにビューを作ってくれる、という考え方。
インフラ屋さんからすると、「sedで設定ファイルを手続き的に書き換えるのではなく、Puppet等の構成管理ツールを使うイメージ(yamlに定義したあるべき姿の通りに裏で設定が変更される)」と言うとわかりみがあるかもしれない。
なんでそんなことになったのかって言うと、端的には、大規模なUIをいちいちエレメント操作して作ってると大変だから、だと思う。
ところでそもそもどうして大規模なUIを作る必要が生まれたんでしょう?
ユーザエクスペリエンスの向上を目指してたらフロントエンドへの要求が肥大化してきた、というのはあるかもしれないけど、他にもバックエンドとの関係性の変化もあると思う。
後述の通り、サーバレスアーキテクチャはいわゆるImmutable Infrastructureの考え方のもとに成り立っており、基本的にステートレスである。
するとバックエンドではなるべくアプリの状態を保持しないため、特にビューに関する状態などはフロントエンドに任せる必要が生じる。この流れが加速してSPAの重要性が増しているのではと考える。
ここ最近のトピック
状態管理
SPAの規模が大きくなってくると、ビューの状態を示すデータの扱いに一定の設計指針が必要となってくる。
Fluxや、それをもとにしたReduxが有名。
最近のフレームワークでは、個別に対応した状態管理用フレームワークがある(React~ReduxやVuexなど)。
最もデファクトに近いのはReduxのイメージだが、Reduxはそれなりに規模が大きなアプリでないとオーバースペックな設計思想のため、より幅広い層に受け入れられそうな設計思想が模索されている様子。
ReactではContext API、FlutterではBLoCやScopedModel(Provider)のようなものも出てきている。
これからも変遷が続くと思われる。
webコンポーネント
フレームワークではなく標準仕様としてコンポーネントを記述する方法がWebComponentsとして定義されつつある。
最近やっと主要ブラウザがサポートし始めたらしい。
https://html5experts.jp/shumpei-shiraishi/24239/
サーバレスアーキテクチャとは?
以前書いた記事でざっくりと。
要は「自前で面倒を見ないといけないサーバ(ハードウェア、仮想マシンやインスタンス)を持たずにシステムを動作させるアーキテクチャ」ということになる。
インフラリソースの管理の煩雑さを解決する動きのひとつにImmutable Infrastructureという考え方があり、自分が思うにサーバレスアーキテクチャは現状におけるその最たる例である。
サーバーレスアーキテクチャでは基本的にステートレスとなる。バックエンドではアプリの状態を保持しない。それによりサーバが停止しても使い捨てて新しいサーバを自動的に立ち上げることで復旧できる。
サーバーレスアプリケーションの開発
本書では、認証にCognito、データ保管にDynamoDB、サーバサイドロジックにLamdaを使ったサーバーレスアプリケーションの例を示している。
最近では、AWS Amplifyを使うことで、より簡便にサーバーレスサービスを扱えるようになっている。(mBaaS。GCPのFirebaseに相当する)
各サービスの詳細は割愛。