世界はインターネットへの移行を進め、Webアプリケーションはもはや新たな職場や店舗と言えるまでに成長しました。現代のWebアプリケーションが果たす多様な目的に対応するために、高いパフォーマンスとカスタマイズ性を備えた設計が必要になります。

この問題を解決するのが、Webアプリケーションアーキテクチャです。

Webアプリケーションアーキテクチャは、ウェブベースのアプリケーションの様々なコンポーネントがどのように構造化されているかを定義します。このアーキテクチャは、Webアプリケーションの性質と目的に特化したものです。Webアプリケーションに間違ったアーキテクチャを選択すると、事業に大きな支障をきたす可能性があります。

この記事では、Webアプリケーションのアーキテクチャの概念を分解し、それがアプリケーションのエンドユーザーエクスペリエンスにどのような影響を与えるかをご説明します。また、Webアプリケーションを最大限に活用するためのベストプラクティスもいくつか紹介します。

Webアプリケーションアーキテクチャとは

議論を始めるにあたり、Webアプリケーションアーキテクチャの定義から始めましょう。

簡単に言うと、Webアプリケーションアーキテクチャとは、Webアプリケーションの様々なコンポーネントが互いにどのように相互作用するかについてのアウトラインのことです。

クライアントとサーバーの関係を定義するだけ、というくらいに単純になることもあります。また、コンテナ化されたバックエンドサーバー群、ロードバランサー、APIゲートウェイ、ユーザー向けのシングルページフロントエンド間の相互関係を定義する、といった複雑な構造にもなり得ます。

とはいえ、プログラミング言語の選択がその中心になることは希です。

Webアプリケーションをどのように設計するかは、そのユーザビリティとコストの最適化の両方において重要な役割を果たします。Webアプリのアーキテクチャの例を図を用いて紹介します。

レコメンドアプリケーションのアーキテクチャの図
レコメンドアプリケーションのアーキテクチャの図(画像出典:Wikipedia

なぜWebアプリケーションアーキテクチャが重要なのか

Webアプリケーションのアーキテクチャは、間違いなく、Webアプリケーションの最も重要な要素の一つになります。特定のアーキテクチャを念頭に置いてWebアプリケーションを開発することで、アプリケーションの保守と成長に関して多くのメリットが得られます。

それどころか、適切なアーキテクチャを選択することで、その利点はさらに増幅されます。

以下では、Webアプリケーションのアーキテクチャの採用を真剣に検討すべき最大の理由をいくつか紹介します。

ビジネスニーズに容易に対応できる

アプリはビジネスへの重要な入口であり、ビジネスニーズは市場の変化に合わせて変化します。それに遅れを取らないためには、流転するニーズに適応できるような柔軟性をアプリに求めることになります。柔軟性を考慮せずにアプリを構築すると、将来的にアプリのわずかな調整を行うために、より多くの時間と労力を費やすことになるでしょう。

Webアプリケーションのアーキテクチャにおいては、将来的に必要となる可能性のある変化を考慮することが重要です。例えば、ECアプリケーションを構築する場合、将来的に拡張し多数の顧客に幅広いサービスを提供することが分かっていれば、モノリシックなアーキテクチャではなくマイクロサービスアーキテクチャを採用し、柔軟性を高めることができます。

一方、1つか2つの要件しかない社内用アプリケーションを構築する場合は、よりシンプルなシステムを選択し、開発をスピードアップさせながらコードのクリーンさを保つことができます。

組織的な開発

先に述べたように、適切なWebアプリケーションアーキテクチャは、優れた開発ロードマップにつながります。アーキテクチャにより、必要に応じてコンポーネントを分離できる十分なモジュール性をシステムにもたらし、各モジュールやコンポーネントに適したプロジェクト構造を選択できます。

アーキテクチャを考慮せずにアプリの開発に着手すると、コンポーネントを再構成したり、チームメンバー間のコラボレーションを促進するための新しいルールを定めたりと、時間と費用を無駄にする可能性があります。その手間やリソースは、当然、別の業務やプロジェクトに投じることができます。

コードベース管理の改善

アプリのコードを書くだけでなく、その管理にもかなりの時間を費やすことになります。プロジェクトファイルの整理、アプリのモジュールへの分割、カスタムパイプラインの設定などなど、開発を円滑に進めるために積極的なメンテナンスが必要となるタスクは枚挙にいとまがありません。

適切なWeb アプリのアーキテクチャを使用すると、変更を簡単に行うことができます。コンポーネント固有のベストプラクティスを実装し、アプリのペインポイントを互いに分離し、各機能の独立性と疎結合を維持することができるのです。これは決して、アーキテクチャがなければできないということではありませんが、適切なアーキテクチャの選定によって、そのすべてがよりシンプルになるということです。

また、あらかじめ定義されたアーキテクチャに従うことで、アプリケーションの開発が容易になり、開発期間も短縮できます。正しいアーキテクチャと適切なバージョン管理戦略を組み合わせることで、開発者は互いに並行して作業し、機能をより速く構築可能です。

また、Webアプリケーションのアーキテクチャは、アプリケーションの将来を保証するものでもあります。アプリケーションのコンポーネントをどのように構成するかについて、確固たる戦略を定義すれば、アプリケーション全体を作り直すことなく、コンポーネントを一つずつ新しい技術に簡単に移行できます。

セキュリティの強化

ほとんどのウェブアプリのアーキテクチャは、コンポーネントを構成する際にセキュリティを考慮しています。開発者は、ユーザーへの提供前に、アプリのセキュリティを向上させる策とステップを計画することができます。

例えば、有料/無料の両方のコンテンツを提供するOTTビデオストリーミングアプリの構築にマイクロサービスを使うのは理にかなっているでしょう。マイクロサービスアーキテクチャでは、アプリをユーザー認証や無料または有料のコンテンツストリーミングなど、事業に適したコンポーネントに分割することが可能です。ユーザー認証モジュールがダウンした際には、認証が復旧するまで有料コンテンツモジュールへのアクセスを制限し、無料コンテンツモジュールは引き続きユーザーが利用できるように、アプリを簡単に構成することができます。

同じアプリが密結合のモノリスとして設計されている場合、認証サービスがダウンすると、アプリケーションが停止するか、有料コンテンツが無料で提供されることになり、何としても避けたい事態になります。

Webアプリケーションアーキテクチャはどのように機能するのか

Webアプリケーションアーキテクチャの仕組みについて話す前に、単純なウェブサイトがどのように機能するか理解しておきましょう。

  1. ユーザーがブラウザーのアドレスバーにアプリのURLを入力するか、リンクをクリック
  2. ブラウザがDNSサーバーでURLを検索し、アプリのIPアドレスを特定
  3. ブラウザがアプリにHTTPリクエストを送信
  4. アプリがコンテンツ(通常はウェブページ)で応答
  5. ブラウザが画面上にウェブページを表示

もう少し深く掘り下げると、今度は「Webアプリケーションが」どのようにリクエストを処理するかがわかります。

  1. ユーザーがフロントエンドユーザーインターフェースを介してアプリにリクエストを送信します。
  2. 関連するキャッシュが設定されている場合、アプリはまずそれをチェックして、クライアントに直接送り返すことができる有効なレコードがあるかどうかを確認します。有効であれば、キャッシュしたコンテンツが送り返され、リクエストは完了となります。
  3. キャッシュがない場合、リクエストがロードバランサーに転送されます。
  4. ロードバランサーが、リクエストを処理できるサーバーインスタンスを特定し、それを転送します。
  5. サーバーインスタンスがリクエストを処理し、必要であれば外部APIを呼び出します。
  6. 結果が一箇所に集まると、サーバーがロードバランサーにレスポンスを送り返します。
  7. ロードバランサーがAPIゲートウェイにレスポンスを返し、APIゲートウェイはフロントエンドクライアントのユーザーにレスポンスを送信します。そして、リクエストは完了となります。

Webアプリケーションアーキテクチャの種類

さて、Webアプリケーションアーキテクチャとは、という基本的な部分を理解したところで、一般的なWebアプリケーションアーキテクチャの種類を詳しく見ていきましょう。

シングルページ

シングルページアプリケーション(SPA)のアーキテクチャは、その名の通りシンプルです。アプリケーション全体が1つのページを土台にしています。ユーザーがアプリケーションを起動すると、他のウェブページに移動する必要はありません。ユーザーがアプリ内を移動する際には、ユーザーの要求に応じた画面を取得しレンダリングする動的な作りになっています。

SPAは、エンドユーザーや消費者に高速でシームレスなエクスペリエンスを提供するという点では優れています。しかし、従来のウェブサイトとは性質を異にするもので、SEOの施策も難しい場合があります。

SPAアーキテクチャの長所

SPAアーキテクチャの長所には、以下のようなものがあります。

  • 高度にインタラクティブなWebアプリケーションを構築できる
  • 拡張が容易
  • パフォーマンスを最適化するのにそれほど労力を必要としない

SPAアーキテクチャの短所

SPAアーキテクチャの欠点には、以下のようなものがあります。

  • ハイパーリンクやSEOの柔軟性が制限される
  • 初期レンダリングが通常遅くなりがち
  • アプリ内のナビゲーションが直感的でないことがある

プログレッシブWebアプリケーション

プログレッシブWebアプリケーション(PWA)はシングルページアーキテクチャ上に構築されるもので、Webアプリケーションにオフライン機能が付加されます。PWAの構築には、CapacitorやIonicなどの技術が使用され、プラットフォーム間で統一されたエクスペリエンスをユーザーに提供することが可能です。

SPAと同様に、PWAはスムーズでシームレスです。サービスワーカーを介してユーザーのデバイスにインストールされる機能が追加され、アプリケーションでより均一な操作性を手にすることができます。

一方、SEOの施策が難しく、インストールしたアプリケーションのアップデートが困難になる可能性があります。

PWAアーキテクチャの長所

PWAアーキテクチャには、以下のような多くの利点があります。

  • アプリは非常にスムーズに動作し、クロスプラットフォームの互換性もある
  • スケーラビリティの面でシンプル
  • オフラインアクセスや、バックグラウンドワーカーやプッシュ通知などのデバイスネイティブなAPIに、開発者がアクセス可能

PWAアーキテクチャの短所

PWAアーキテクチャの短所としては、以下のようなものが考えられます。

  • リンク管理やSEOのサポートは限定的
  • オフラインのPWAへの更新のプッシュは、ネイティブアプリよりも複雑
  • ウェブブラウザやオペレーティングシステム間でのPWAのサポートが限定的

サーバーサイドレンダリング

サーバーサイドレンダリング(SSR)では、フロントエンドのウェブページは、ユーザーから要求された後にバックエンドのサーバーでレンダリングされます。これにより、クライアントデバイスは静的なHTML、CSS、JSのウェブページを受け取るため、負荷を軽減することができます。

SSRアプリは、ブログやECサイトで非常に人気があります。リンク管理やSEOの施策が簡単であるためです。また、SSRアプリは、画面表示のためにクライアントによるJSコードの処理が必要ないため、最初のレンダリングが非常に速い傾向にあります。

SSRアーキテクチャの長所

SSRアーキテクチャの長所は、以下のとおりです。

  • SEOの施策に重点を置いたウェブサイトに最適
  • ほとんどの場合、最初のページの読み込みはほぼ一瞬で完了
  • キャッシュサービスと組み合わせて、アプリのパフォーマンスをさらに向上させることができる

SSRアーキテクチャの短所

SSRアーキテクチャを使うことの欠点はいくつかある。

  • サーバーがページを完全に生成するのに時間がかかり、最初のレンダリングが遅れることがあるため、複雑で重いウェブページには推奨されない
  • ユーザーインターフェースをあまり重視せず、スケーラビリティやセキュリティの向上のみを目的としたアプリに推奨されることが多い

プリレンダリングアプリケーション

プリレンダリングアプリケーションは、静的サイトを生成するものです。このアーキテクチャでは、アプリのフロントエンドのWebページが事前に生成され、HTML、CSS、JSファイルとしてサーバーに保存されます。ユーザーがページを要求すると、そのページが直接取得の上、表示されます。このため、アプリが非常に高速で、あらゆる種類の読み込み時間を最小限に抑えることができます。ただし、このアーキテクチャでは、ビルドプロセス中にウェブページがレンダリングされるため、アプリのビルド時間が長くなります。

Webアプリのプリレンダリングは、ブログや製品情報など、頻繁に変更されない静的なコンテンツを作成するのに適しています。また、テンプレートを活用することで、ウェブページのデザインを簡素化することもできます。しかし、このアーキテクチャで動的なWebアプリを構築することはほぼ不可能です。例えば、パスにクエリを取る検索ページ(https://myapp.com/search/foo+barのようなもの)を構築しようとしているのなら、この選択肢は避けるべきでしょう。

アプリのルートが全て(考えられる全て)ビルドプロセスでプリレンダリングされる仕様です。そのため、ビルド中にプリレンダリングできない無限の可能性が介在すると、実現は不可能です(そもそも、意味が見出せません)。

プリレンダリングアーキテクチャの長所

プリレンダリングアプリケーションアーキテクチャの利点としては、以下のようなものが挙げられます。

  • ウェブページが純粋なHTML、CSS、JSで生成されるため、そのパフォーマンスはバニラ(Vanilla)JSを使用して構築されたアプリのそれに似たものになる
  • アプリのあらゆる経路を把握すれば、SEOの施策を打つことが非常に容易になる

プリレンダリングアーキテクチャの短所

他のアーキテクチャモデルと同様に、プリレンダリングには欠点があります。

  • 動的なコンテンツは提供できない
  • アプリケーションに何らかの変更を加えると、完全に再構築し、ゼロからデプロイすることになる

アイソモーフィックアプリケーション

アイソモーフィックアプリケーションとは、サーバーサイドレンダリングとSPAが混在するアプリケーションのことを指します。このようなアプリは、まずサーバー上で通常のサーバーサイドレンダリングアプリとしてレンダリングされます。そして、クライアントが受け取ると、ハイドレーションを経て、仮想DOMを用いることにより高速かつ効率的なクライアント処理を実現します。これにより、実質的にアプリはシングルページアプリケーションとなります。

アイソモーフィックは、両者の長所を併せ持つものです。SPAの強みとして、クライアント側での超高速処理と機能的なユーザーインターフェースが確保できます。また、サーバーサイドレンダリングにより、素早い初回レンダリングと本格的なSEOの施策の実施、そして、リンクのサポートが可能になります。

アイソモーフィックアーキテクチャの長所

アイソモーフィックアプリケーションを使用する利点は以下の通りです。

  • アイソモーフィックアプリケーションは、初期レンダリングが非常に速く、SEOの面でも強さを発揮する
  • 読み込み後にSPAになるため、クライアントでのパフォーマンスも良好

アイソモーフィックアーキテクチャの短所

アイソモーフィックアプリケーションの短所としては、以下のようなものが挙げられます。

  • このようなアプリのセットアップには、熟練した人材が必要になる
  • アイソモーフィックなアプリをデザインする場合、技術スタックの選択肢は限られ、実質的にはほんの一握りのJSベースのライブラリやフレームワークから選ぶことになる

サービス指向アーキテクチャ

サービス指向アーキテクチャ(SOA)は、アプリを構築する従来のモノリス方式に代わる最も人気のある選択肢の1つです。このアーキテクチャでは、Webアプリケーションは、ビジネスの機能単位を表すサービスに分解されます。各サービスが緩やかに結合し、メッセージパッシングという手段で互いに作用し合います。

サービス指向アーキテクチャは、アプリケーションの技術スタックに安定性とスケーラビリティをもたらします。しかし、SOAにおけるサービスのサイズは明確に定義されておらず、通常、技術的なコンポーネントではなく、ビジネスコンポーネントに結びつけられるため、メンテナンスが問題になることがあります。

サービス指向アーキテクチャの長所

サービス指向アーキテクチャの主な利点は以下の通りです。

  • 拡張性と信頼性の高いアプリを構築するのに有用
  • コンポーネントは再利用可能であり、共有と高い親和性があるため、開発とメンテナンスの労力が軽減できる

サービス指向アーキテクチャの短所

サービス指向アーキテクチャを使用する際の欠点は以下の通りです。

  • SOAアプリは、各サービスのサイズと範囲が固定されていないため、まだ100%の柔軟性があるわけではなく(保守が困難なエンタープライズアプリケーションサイズのサービスが存在する可能性がある)
  • コンポーネントの共有により、サービス間の依存関係が発生する

マイクロサービス

マイクロサービスアーキテクチャは、サービス指向アーキテクチャの問題点を解決するために考案されたものです。マイクロサービスでは、さらにモジュール化されたコンポーネントを組み合わせることで、Webアプリを構築します。しかし、各コンポーネントを小さく保ち、境界付きのコンテキストを持つことに重点を置いています。境界付きコンテクスト(「境界づけられたコンテキスト」)とは、基本的に各マイクロサービスのコードとデータが、他のマイクロサービスへの依存を最小限に抑えながら結合することを意味します。

マイクロサービスアーキテクチャは、いつの日か数千人、数百万人のユーザーにスケールすることを目指すアプリを構築するのに、おそらく最適のアーキテクチャと言えるでしょう。各コンポーネントには弾力性があり、スケーラブルで、保守が容易です。しかし、マイクロサービスベースのアプリのDevOpsライフサイクルを維持するためには、通常よりも多くの労力が必要となります。

マイクロサービスアーキテクチャの長所

マイクロサービスアーキテクチャの長所には、以下のようなものがあります。

  • アプリのコンポーネントは、サービス指向アーキテクチャのものに比べて、高度にモジュール化され、独立しており、再利用が可能
  • 各コンポーネントは独立して拡張でき、ユーザーのトラフィックの変化に対応できる
  • マイクロサービスベースのアプリケーションは、フォールトトレラントが高い

マイクロサービスアーキテクチャの短所

マイクロサービスアーキテクチャの短所は、以下のようなものが考えられます。

  • 小規模なプロジェクトでは、マイクロサービスアーキテクチャの維持に多大な労力を要する場合がある

サーバーレス

サーバーレスアーキテクチャは、Webアプリのアーキテクチャの世界におけるもう1つの新しい概念です。このアーキテクチャは、アプリケーションを、それが遂行する機能という観点から分解することに焦点を当てています。そのような機能は、リクエストが来たときに呼び出されるものとして、FaaS(Function-as-a-Service)プラットフォームでホスティングされます。

今回ご紹介している他の多くのアーキテクチャとは異なり、サーバーレスアーキテクチャを使用して構築されたアプリは、常時稼働しているわけではありません。呼び出されるのを待ち、呼び出されたら、定義された処理を実行し、結果を返すという、関数と同じような振る舞いをします。そのため、メンテナンスコストを削減でき、手間をかけずに高いスケーラビリティを実現できます。ただし、長時間稼働するタスクの実行は難しいとされています。

サーバーレスアーキテクチャの長所

ここでは、サーバーレスアーキテクチャの主な強みを紹介します。

  • サーバーレスアプリは、高度かつ管理の容易なスケーラビリティを誇り、リアルタイムでトラフィックに適応し、インフラストラクチャの負荷を軽減することも可能
  • このようなアプリでは、サーバーレスプラットフォームの従量課金モデルを利用して、インフラストラクチャのコストを削減することができる
  • サーバーレスアプリは、関数を書いて、Firebase Cloud FunctionsやAWS Lambdaなどのプラットフォームでホストするだけなので、構築とデプロイが非常に簡単

サーバーレスアーキテクチャの短所

以下は、サーバーレスアーキテクチャの欠点です。

  • このようなアーキテクチャでは、長時間実行されるタスクについてはコストがかかることがある
  • 関数が長い時間を経てリクエストを受け取るとき(コールドスタートと呼ばれる)時間がかかり、エンドユーザーのエクスペリエンスを害する可能性がある

Webアプリケーションアーキテクチャの各層

上で見たWebアプリケーションのアーキテクチャは、それぞれ全く異なるように思えるかもしれませんが、そのコンポーネントは、事業の目標を達成する上で明確な層に分類することが可能です。

プレゼンテーションの層

プレゼンテーションの層は、Webアプリケーションの中でエンドユーザーに公開されるすべてを意味します。主に、フロントエンドクライアントで構成されます。しかし、フロントエンドを動的にするためには、バックエンドに記述したロジックも組み込まれます。これにより、ユーザーのプロファイルや要件に合わせてカスタマイズを施したUIを提供することができます。

この層を構築するために、3つの基本技術が使用されます。HTML、CSS、JavaScriptです。HTMLはフロントエンドのレイアウトを、CSSはフロントエンドのスタイルを、そしてJSはフロントエンドに命を吹き込みます(つまり、ユーザーがフロントエンドにアクセスしたときの動作を制御するもの)。これら3つの技術の上に、あらゆる種類のフレームワークを使用することで、開発を容易にすることができます。人気の高いフロントエンドフレームワークには、Laravel、React、NextJS、Vue、GatsbyJSなどがあります。

ビジネスの層

ビジネスの層は、アプリの動作のロジックを保持・管理する役割を担います。通常は、クライアントからのリクエストを受け付け、それを処理するバックエンドサービスになります。ユーザーがアクセスできる内容を制御し、ユーザーのリクエストに応えるためにインフラストラクチャをどのように利用するかを決定します。

ホテル予約アプリであれば、クライアントアプリは、ユーザーがホテル名やその他の関連データを入力するポータルとして機能します。しかし、ユーザーが検索ボタンをクリックするとすぐに、ビジネスの層がリクエストを受け取り、要件に一致するホテルの部屋を探すロジックを実行します。クライアントは、その結果がどのように生成されたのか、また、各項目がどのようなアルゴリズムで配置されているのかさえも知ることなく、ただホテルの部屋の一覧を受け取ることになります。

このような層が存在することで、中身にあるロジックがクライアント、ひいてはユーザーに公開されることはありません。ビジネスを司るロジックを分離することは、支払いや医療記録の管理など、機密性の高い業務に非常に有効です。

永続化の層

永続化の層は、データストアへのアクセスを制御する役割を担います。データストアとビジネスの層の間にある抽象化されたレイヤーとして機能します。ビジネスの層からのデータ関連の呼び出しをすべて受け取り、データベースとの安全な接続を確立します。

この層は通常、データベースサーバーで構成されます。オンプレミスのインフラにデータベースとデータベースサーバーをプロビジョニングして自分で設定することも、AWS、GCP、Microsoft Azureなどの大手クラウドインフラプロバイダーによるリモート/マネージドソリューションを選択することも可能です。

Webアプリケーションの構成要素

Webアプリケーションのアーキテクチャを理解したところで、Webアプリケーションを構成する各コンポーネント見ていきましょう。サーバーサイドのコンポーネントとクライアントサイドのコンポーネント、そしてバックエンドとフロントエンドのコンポーネントの2つの大きな項目に分類し説明します。

サーバーサイドコンポーネント

サーバーサイドコンポーネントは、Webアプリケーションのバックエンドに存在するコンポーネントです。ユーザーには直接公開されず、Webアプリケーションの最も重要なビジネスロジックとリソースを保持します。

DNSとルーティング

DNSは、アプリがウェブに公開される方法を制御する役割を果たします。DNSレコードは、HTTPクライアント(ブラウザも含む)がアプリのコンポーネントを検索してリクエストを送信するのに使用されます。DNSはまた、フロントエンドクライアントが内部でWebサーバーやAPIエンドポイントの場所を解決してリクエストを送信し、ユーザーの操作を処理するためにも使用されます。

Webアプリケーションアーキテクチャのもう一つの一般的なコンポーネントに、ロードバランサーがあります。HTTPリクエストを複数をサーバー間で分散させるのに使用します。複数のウェブサーバーを設置する目的は、耐障害性を高める冗長性を維持することと、トラフィックを分散し高いパフォーマンスを維持することです。

APIエンドポイントは、バックエンドのサービスをフロントエンドのアプリケーションに公開するのに使用されます。APIエンドポイントは、クライアントとサーバー、時には複数のサーバー間の通信を円滑にするのに有用です。

データストレージ

データストレージは、最新のアプリケーションにとって重要な要素になります。ユーザーセッションをまたいで保持する必要のあるアプリケーションデータが存在するためです。データストレージには以下の2つのタイプがあります。

  • データベース:データベースは、高速にアクセスしたいデータを保存するために使用されます。通常、アプリケーションから定期的にアクセスされる少量のデータを保存するのに効果を発揮します。
  • データウェアハウス:データウェアハウスは、過去のデータを保存するためのものです。これは通常、アプリケーションではあまり必要とされませんが、ビジネスインサイトといったデータを生成するのに定期的に処理されます。

キャッシュ

キャッシュは、ユーザーに素早くコンテンツを提供するために、Webアプリケーションのアーキテクチャによく実装される機能です。アプリのコンテンツの大部分は、常にではないにせよ、ある程度の期間、繰り返し使用されるものです。データストアからアクセスして処理してからユーザーに送り返すのではなく、キャッシュとして保持されることがよくあります。Webアプリケーション全体で使用される最も一般的な2種類のキャッシュを以下に示します。

  • データキャッシュ:データキャッシュにより、頻繁に変更されない(定期的に使用される)データに、アプリケーションが簡単かつ素早くアクセスできるようになります。RedisやMemcacheなどのサービスにより、データをキャッシュすることで、同じデータを何度も取得する(高価になり得る)データベースクエリを実質的に節約することができます。
  • ウェブページのキャッシュ:CDNは、Redisがデータをキャッシュするのと同じように、ページのキャッシュを行います。頻繁に変更されないデータのみがキャッシュされるのと同様に、通常、静的なウェブページのみをキャッシュすることが推奨されます。サーバーサイドレンダリングのWebアプリケーションでは、コンテンツが非常に動的であることが想定されるため、キャッシュはあまり効果がありません。

ジョブとサービス

ユーザーへのインターフェースの公開(フロントエンド)とリクエストの処理(バックエンド)とは別に、Webアプリケーションのコンポーネントには、もう一つあまり一般的ではないカテゴリーがあります。それがジョブです。一般的にバックグラウンドのサービスであり、時間的な制約や同期性のないタスクを実行することを目的としています。

CRONジョブは、決まった時間帯に何度も実行されるものです。バックエンドでの実行タイミングを定め、設定された時刻に自動的にメンテナンス等を実行します。一般的な使用例としては、データベースから重複している/古いレコードを削除する、顧客にリマインダーメールを送信する、などがあります。

クライアントサイドコンポーネント

クライアントサイドコンポーネントは、直接または間接的にユーザーに公開されるコンポーネントです。

このカテゴリーには、主に2種類のコンポーネントがあります。

フロントエンドのユーザーインターフェース

ユーザーインターフェースは、アプリケーションの視覚的な側面です。ユーザーがサービスにアクセスするためにこれを目にし、操作します。

フロントエンドインターフェースは、主に3つの技術に基づき構築されます。それがHTML、CSS、JavaScriptです。フロントエンドのユーザーインターフェースは、それ自体がアプリケーションであり、独自のソフトウェア開発ライフサイクルを持ち得ます。

フロントエンドのユーザーインターフェースは、ユーザーに直接公開されるため、ビジネスロジックがこれに組み込まれることはあまりありません。悪意のあるユーザーがフロントエンドアプリケーションのリバースエンジニアリングを試みると、ビジネスの仕組みに関する情報を入手し、企業のなりすましやデータの盗難といった違法行為を行う可能性が懸念されます。

また、フロントエンドのユーザーインターフェースはユーザーに直接公開されるため、読み込み時間や応答性を最小限に抑えるよう最適化する必要があります。そうすることで、ユーザーにより良い体験を提供し、それによってビジネスの成長を促進できる可能性があります。

クライアントサイドのビジネスロジック

シンプルな操作を迅速に実行するために、クライアント側にビジネスロジックを配置するケースもあります。通常、フロントエンドアプリケーション内に存在するクライアントサイドロジックは、サーバーへの無駄な移動を省き、ユーザーに対してより高い操作性を提供するのに有用です。

これは、クライアントサイドコンポーネントでは任意の機能です。場合によっては、アプリのビジネスロジックが完全にクライアントサイドに格納されることもあります(特に、従来のバックエンドサーバーを使用せずに構築する場合)。BaaSのような最新のソリューションでは、認証、データストレージ、ファイルストレージなどに、フロントエンドアプリから随時アクセスすることができます。

コードを圧縮または難読化して、リバースエンジニアリングの可能性を最小限に抑え、ユーザーに提供する方法があります。

Webアプリケーションコンポーネントのモデル

Webアプリケーションのアーキテクチャには複数のモデルがあり、それぞれにサーバーがデータストアに接続する方法の違いが見られます。

1 台のサーバー、1 つのデータベース

最もシンプルなモデルは、1台のサーバーが1つのデータベースインスタンスに接続するものです。このモデルは、実装と保守が容易であり、本番環境での稼動もそれほど難しくはありません。

そのシンプルさゆえに、このモデルは学習用や、高いトラフィックにさらされることのない小規模な実験用アプリケーションに適しています。初心者の開発者でも、このアプリケーションを簡単にセットアップして触れることで、Webアプリケーション開発の基礎を学習することができます。

しかし、このモデルは非常に信頼性が低いため、本番環境では使用しないことをおすすめします。サーバーやデータベースのいずれかに問題が発生すると、すぐにダウンが発生し、事業やプロジェクトに悪影響が出る可能性があります。

複数サーバー、1つのデータベース

このモデルは、1つの共通のデータベースインスタンスと冗長性のために複数のサーバーを設定することで、アプリケーションをより高度なものにします。

複数のウェブサーバーが同時にデータベースにアクセスするため、不整合の問題が発生する可能性があります。それを避けるために、ウェブサーバーはステートレスで設計します。つまり、サーバーはセッションを越えてデータを保持せず、単にデータを処理してデータベースに格納するだけになります。

このモデルで作られたアプリでは、複数のウェブサーバーが存在することで耐障害性が高まるため、以前のモデルよりも確かに信頼性が高くなります。しかし、データベースは依然として1つの共通インスタンスであるため、アーキテクチャの中で最も弱い箇所となり、障害の原因となる可能性があります。

複数サーバー、複数データベース

このモデルは、Webアプリケーションを設計する上で最も一般的かつ歴史あるモデルの1つです。

このモデルでは、アプリケーションロジックをロードバランサーの背後で、複数の同一のウェブサーバーインスタンスとして展開します。また、データストアは複数のデータベースインスタンスで管理し、フォールトトレランスを強化します。

また、利用可能なインスタンス間でデータベースを分割してパフォーマンスを向上させたり、データストア全体の複製を維持して冗長性を確保したりすることもできます。いずれの場合も、データベースのいずれかのインスタンスに障害が発生しても、アプリケーションが完全に停止することはありません。

このモデルは、その信頼性と拡張性から高く評価されています。しかし、このモデルを使用したアプリケーションの開発と保守は比較的複雑になりがちで、(給料のかさむ)熟練の開発者が必要になります。そのため、このモデルは大規模に構築する場合にのみ推奨されます。

アプリサービス

上記の3つのモデルはモノリシックなアプリケーションに適していますが、モジュラーアプリケーションにはもう1つのモデルがあります。

アプリケーションサービスモデルは、ビジネスの機能に基づいて、アプリケーションをより小さなモジュールに分解するものです。そのモジュールは、機能のように小さくなることも、サービスのように大きくなることもあります。

各ビジネスの機能を独立させることで、スケーラブルになります。モジュールは、それぞれ単独でデータベースに接続することができます。モジュールのスケーラビリティの必要性に合わせて、専用のデータベースインスタンスを用意することも可能です。

非モノリシックなアプリの中では、このモデルは非常に人気があります。レガシーかつモノリシックなアプリは、そのスケーラビリティとモジュール性という利点を生かすために、このモデルに移行されることがよくあります。しかし、このようなモデルで構築されたアプリを管理するには、先と同じく熟練した開発者、特にDevOpsとCI/CDの経験が必要になるものです。

Webアプリケーションアーキテクチャのベストプラクティス

選択したWebアプリケーションアーキテクチャを最大限に活用するために、Webアプリケーションプロジェクトに導入できるベストプラクティスをいくつか見ていきたいと思います。

1. フロントエンドをレスポンシブにする

とても重要な点です。常にレスポンシブなフロントエンドを目指しましょう。内側がどんなに巨大で複雑なWebアプリケーションであっても、フロントエンドのページ、アプリ、画面を通じて、その価値がユーザーに届きます。

もし、その画面が直感的でなかったり、遅かったりしたら、ユーザーは、Webアプリケーション(例えそれが優れたシステムを誇るものでも)を使う気にすらならないでしょう。

そのため、アクセシブルで使いやすく、軽量なフロントエンドを設計することは、非常に重要なことです。

ユーザーにとって何がベストなのか。これを理解するにはUI/UXのベストプラクティスに目を通すのが一番です。ユーザーがアプリを最大限に活用できるように、ユーザーフレンドリーなデザインとアーキテクチャを作ることに長けたプロから知恵を借りることをおすすめします。

総じて、ユーザーに製品を提供する前に、フロントエンドの応答性について真剣に検討しておくことをお勧めします。

2. 読み込み時間の監視

フロントエンドは、理解しやすいだけでなく、読み込みが速いことも必要です。

また、Unbounceによると、約70%の消費者が、ページの表示時間がオンラインサイトで買い物をする際の重要な要素であると認めています。

モバイルネイティブのアプリケーションを設計する場合、通常、ユーザーのデバイスの仕様を確認することはできません。アプリの要件を満たさないデバイスは、通常、「アプリをサポートしない」ものとみなされます。

しかし、これはウェブではまったく異なります。

Webアプリケーションでは、ユーザーは最新のApple Macbook M1 Proから年代物のBlackberryやNokiaの携帯電話まで、あらゆるものを使って、アプリを閲覧することができます。このような幅広いユーザーに対して、フロントエンドの利便性を最適化することは、時に困難になり得ます。

フロントエンドのパフォーマンスといえば、LightHouseやGoogle PageSpeedのようなサービスが思い浮かぶでしょう。このような計測ツールを使って、デプロイする前にフロントエンドアプリの性能を精査する必要があります。その多くが、アプリのパフォーマンスを向上させる実用的なヒントを提示してくれます。

アプリのパフォーマンスの最後の5~10%は、通常、ユースケースに特有のもので、アプリとその技術をよく知っている人でなければ対処できません。そのような場合には、ウェブパフォーマンスに賢く投資するという手もあります。

3. 可能な限りPWAを優先する

先にも述べたように、PWAは時代の先端を行く技術です。ほとんどのユースケースに対応でき、主要なプラットフォームで均一な利便性を実現します。

アプリ開発時には、できるだけPWAの使用を検討しておきたいところです。ウェブとモバイルを横断するネイティブな体験は、ユーザーにとって大きなメリットになり、開発側の作業量も大幅に減らすことができます。

また、PWAは読み込みが速く、最適化が容易で、素早く構築することができます。PWAを選択することで、開発からビジネスへと、早い段階で日々の業務の焦点を移すことができます。

コードベースは常にクリーンかつ簡潔に

コードベースがクリーンであれば、あらゆる問題を発見し、損害が発生する前に解決することができます。コードベースが必要以上に問題を引き起こさないようにするヒントをいくつか示します。

  • コードの再利用に重点を置く:コードベース全体に同じコードを複数保持することは、冗長なだけでなく、矛盾が生じ、コードベースの維持が困難になる可能性もあります。可能な限り、コードの再利用に注力しましょう。
  • プロジェクトの構造を計画する:ソフトウェアプロジェクトは徐々に大きくなる可能性があります。コードの構成やリソースの構造を計画した上で始めないと、有用なコードを書くよりも、ファイルを探すことに多くの時間を費やしてしまうかもしれません。
  • ユニットテストを書く:どのようなコードにも、破損の可能性があります。すべてのコードを手作業でテストするのは現実的ではないので、コードベースのテストを自動化する戦略が必要です。テストランナーやコードカバレッジツールは、単体テストの結果を確認するのに有用です。
  • 高いモジュール性:コードを書くときは、常にモジュール性に重点を置いてください。他のコードと密に結合しているコードを書くと、テストや再利用、必要に応じて変更することが難しくなります。

5. CI/CDプロセスを自動化する

CI/CDとは、Continuous Integration/Continuous Deployment(継続的インテグレーション/継続的デプロイメント)の略です。CI/CDプロセスは、プロジェクトのビルド、テスト、デプロイを容易にするため、アプリケーションの開発において非常に重要です。

しかし、毎回手動で実行する必要はありません。代わりに、プロジェクトのアクティビティに基づいて自動で起動するパイプラインを設定することができます。たとえば、コードをバージョン管理システムにコミットするたびに、自動的にテストを実行する、といったパイプラインを設定可能です。他にも、リリースが作成されるたびに、コードリポジトリからクロスプラットフォームアーティファクトを生成するなど、より複雑なケースもたくさんあります。

CI/CDパイプラインをどのように活用するかは、現場の状況次第です。

6. セキュリティ機能を組み込む

モダンなアプリは、複数のコンポーネントで構成されているものがほとんどです。次のようなアプリを例にとって考えてみましょう。

 サーバーレスWebアプリのアーキテクチャの例
サーバーレスWebアプリのアーキテクチャの例

クライアントのリクエストは、APIゲートウェイを経由してアプリに送られます。このゲートウェイは現在、アプリのホームモジュールへの直接のリクエストのみを許可していますが、将来的にはホームモジュールを経由せずに、より多くのコンポーネントにアクセスできるようになる可能性があります。

次に、ホームモジュールは、アクセスを許可する前に、外部の認証BaaSをチェックします。認証が完了すると、クライアントは「プロフィールの更新」や「プロフィールの表示」ページにアクセスすることができます。これらのページは両方とも、プロファイルデータを処理する共通のデータベースソリューションと相互にやり取りしながら機能します。

ご覧のように、このアプリケーションは、オンラインディレクトリの非常に基本的かつ最小限のバージョンとみなすことができるでしょう。自分のプロフィールを追加/更新したり、他のプロフィールを表示したりすることができます。

上の図のアーキテクチャのコンポーネントを簡単に説明します。

  • 青いボックス:アプリのモジュールで、マイクロサービスやサーバーレス機能としてホスティングされ得る
  • 赤のボックス:認証とデータベースを提供する外部BaaSコンポーネント
  • 緑のボックス:クライアントから届くリクエストを調整するルーティングコンポーネント
  • 黒のボックス:ユーザーに公開されるクライアントアプリケーション

上記の各色のコンポーネントは、様々な種類のセキュリティ上の脅威にさらされやすくなっています。続いて、露出を最小限に抑えるために注目できるセキュリティについていくつか紹介します。

  • アプリモジュール(青色)─サーバーレス機能であるため、そのセキュリティを強化するヒントをいくつか示します。
    • アプリケーションの機密情報を分離し、ソースコードから独立して管理
    • IAMサービスによるアクセス制御を維持する
    • SASTなどで、セキュリティ上の脅威を発見するテストを改善する
  • 外部サービス(赤色)
    • 外部サービスのIAMモジュールで制御を設定しアクセスを規制する
    • APIのレート制限を選択する
    • データベースなどのサービスでは、プロフィールのデータにアクセスできる人、ユーザーのデータを閲覧できる人など、より細かい制御権限を設定する(Firebaseなど多くのサービスでは、このようなルールを細かく設定できるようになっています)
  • ルーティングコンポーネント(緑)
    • 他のコンポーネントと同様に、アクセス制御を実装する
    • 認可を設定する
    • CORS などの標準的なベストプラクティスを再確認する
  • クライアント
    • クライアントからアプリの内部構造が漏れないようにする
    • リバースエンジニアリングの可能性を最小限にするため、クライアントコードを難読化する

これらはほんの一握りですが、アプリのセキュリティは複雑であり、攻撃者のあらゆる手を考え手を打っておくことが重要です。アプリのセキュリティは、アプリのアーキテクチャ全体に分散して言えることです。

7. ユーザーフィードバックの収集

ユーザーからのフィードバックは、ビジネスと技術的なパフォーマンスの観点から、アプリがどの程度機能しているかを理解する重要な指標です。世界で最も軽量でスムーズなアプリを構築することができても、ユーザーの期待に応えなければ、すべての努力が水の泡になってしまいます。

ユーザーからのフィードバックを集めるには、さまざまな方法があります。匿名でのアンケートが一般的ですが、ユーザーの活動を追うヒートマップなど、洗練されたソリューションを採用することもできます。

フィードバック収集方法の選択も重要ですが、収集したフィードバックに対してアクションを起こすことが肝要です。顧客は、自分たちの問題に耳を傾ける企業を好みます。マクドナルドやテスラなどの大手企業はこれを実践しており、市場で結果を出し続ける理由の一つとなっています。

まとめ

ウェブには様々なアプリケーションが群雄割拠しており、それぞれが独自の方法で設計されています。複数のタイプのアーキテクチャが、Webアプリケーションの多様化や、世界中のユーザーへのサービス提供の道を作っているのです。

今回の記事では、ウェブアプリのアーキテクチャのさまざまなモデルを分解し、それがアプリケーションの成長にとっていかに重要であるかを解説しました。

あなたが特に注目しているWebアプリアーキテクチャはありますか?お気軽にコメント欄からお聞かせください。

Kumar Harsh

Kumar is a software developer and a technical author based in India. He specializes in JavaScript and DevOps. You can learn more about his work on his website.