AI can fly !!

AI がやりたい Web エンジニアのアウトプット (AI の知識は無い)

【最近のお仕事】モバイル向け Web アプリケーション開発 (アーキテクチャと技術スタックの紹介)

Architecture

はじめに

先日、担当するプロジェクトでモバイル向け Web アプリケーションの二次開発分をリリースしたので、備忘録も兼ねて現時点で採用しているアーキテクチャと技術スタックについて紹介します。

当 Web アプリはマネージャーとエンジニア (私) の二名体制によるスクラッチ開発で昨年ローンチされ、今回のプロジェクトはチャットや外部 API からのデータ取得等の機能追加を目的としたものでした。

プロジェクトメンバは昨年同様、マネージャーとエンジニア (私) の二名体制になります。

開発期間は設計を含めて片手間で三か月程度、実質一か月~一か月半で仕上げましたが、なんとか納期までにはリリースできたものの完全に工数を見誤りました…

後半は土日も含めて毎日深夜まで…おっと、それでは気を取り直して駆け足で紹介していきます。

アプリの詳細な仕様については、守秘義務などの兼ね合いから記載しませんので悪しからず。

アーキテクチャ

バックエンドは Firebase (および、Google Cloud) をメインとしたサーバレスアーキテクチャを採用し、フロントエンドは Angular を使用した SPA (Single Page Application) で構築しています。

当 Web アプリケーションの要求仕様の一つとして、他社ハードウェアからのメール受信 (Gmail) をトリガとするバックエンド処理がありますが、こちらは Gmail APIGoogle Cloud の Cloud Pub/Sub で対応しました。

今気付きましたが、クラウド環境、バックエンドからフロントエンド、ターゲットとなるモバイル端末 (Android) に至るまで Google で統一されていますね。

アーキテクチャ全体を通して、比較的 Google 製品はシンプルで分かりやすく、とっつきやすさと使い勝手が良いと感じています。

最近、別のプロジェクトで Microsoft Azure を使用していますが、断然 Google Cloud の方が扱いやすいです…

技術スタック

フロントエンド

Angular

SPA で Web アプリケーションを構築するにあたり、開発プラットフォームはこれまで複数の開発実績がある Angular を採用しました。

Angular は開発に必要なパッケージやツールのほとんどが公式にサポートされており、別途サードパーティ製のパッケージなどを組み合わせるコストが発生せず、一体感のある開発体験を行えるのがメリットの一つです。

今回バックエンドとして採用した Firebase との親和性も高く、後述する Angular 公式ライブラリの一つである AngularFire を使用することで、より自然に Angular のスタイルに則したコードを記述することができます。

angular.jp

AngularFire

Firebase を操作するための JavaScript SDK をラップし、 Angular に適したスタイルのコードを書くことができる Angular 公式ライブラリです。

Firebase の各製品を操作する SDK を Service として Component に DI したり、 Angular CLI と連携して Angular アプリを Firebase へデプロイするなど、 Angular で Firebase の開発をするには必須のライブラリと言えます。

github.com

Angular/PWA

PWA とは Web アプリケーションを端末へインストールしたり、オフラインでの操作やバックグラウンドでのプッシュ通知の受信など、ざっくり言えば Web アプリでネイティブアプリのような機能を実現するための技術です。

今回は Firebase Cloud Messaging を使用して送信されたプッシュ通知の受信と表示を行うため、 Angular/PWA を使用しました。

Service Worker のおかげで意図せず初期表示が高速になる恩恵が得られましたが、キャッシュのコントロールなどは行っていないため、アプリ更新時は手動でブラウザを更新するなどのひと手間が必要になります。

ただ、当アプリのリリースサイクルはプロジェクト単位でのリリースとなるため、特に問題にはなりませんでした。

developer.mozilla.org

Angular Flex-Layout

Angular でモバイルファーストなレスポンシブデザインを行うため、 Flexbox CSS とメディアクエリを中心とした Angular 公式パッケージの一つである Angular Flex-Layout を使用しました。

当アプリはモバイル (Android) 端末をターゲットとしていますが、 PC ブラウザでもレイアウトが崩れずに操作が可能なレスポンシブデザインを実現しています。

github.com

Angular Material

Angular 公式の UI ライブラリで、 Material Design を採用したコンポーネントが数多く提供されています。

一つ一つのコンポーネントが Angular の Module として提供されているため、コンポーネントのタグを書くことで簡単に配置でき、プロパティバインディングやイベントハンドリングも容易です。

洗練された Material Designコンポーネントを組み合わせるだけで簡単にそれっぽい Web アプリケーションを作ることができますが、デフォルトのデザインのままでは他との差別化が難しいという点はデメリットと言えなくもありません。

material.angular.io

NgRx

Angular に Redux (Flux アーキテクチャ) のような状態管理の各種機能を提供するライブラリです。

Angular ではシングルトンである Service クラスを使用することで状態の管理を行うことができますが、 NgRx を使用すれば決まったルールの中で一貫した思想に基づいたコードを書くことができます。

プロジェクトやエンジニアごとに思想が異なるオレオレ状態管理は、複数名での開発や運用・保守の場などでは非常に大きな障害・負債になりかねず、プロジェクト初期の学習コストを差し引いてもデファクトスタンダードになっている状態管理技術の導入はメリットがあると思います。

ngrx.io

バックエンド

Firebase

言わずと知れたモバイル・ Web アプリケーション開発プラットフォームで、フルマネージドな Web ホスティングサービスやドキュメントデータベースなどがサーバレス (Saas) で提供されています。

提供元は天下の Google 様です。

必要に応じて複数の製品を組み合わせ、インフラを意識せずに、よりフロントエンドに注力したアプリケーション開発を行うことができます。

firebase.google.com

Firebase Hosting

HTML や CSS などの静的コンテンツだけでなく、 Express などの動的コンテンツもホストできる (らしい) Web ホスティングサービスです。

今回は Angular アプリケーションのホスティングと、後述する Cloud Functions へのリダイレクトを行っています。

firebase.google.com

Firebase Authentication

電話番号やメールアドレス、パスワード等を利用したユーザ認証をアプリケーションへ提供するサービスです。

アプリからのユーザ登録や各種アカウントによるログインもサポートしますが、今回は予め決められたユーザ (メールアドレス) のみ利用可能な Web アプリケーションということで、事前登録されたメールアドレスとパスワードによるログイン認証機能を実装しました。

firebase.google.com

Cloud Firestore

スケーラブルなクラウドホストの NoSQL データベースで、アプリケーションから SDK を通して直接アクセスが可能です。

リアルタイムリスナーという仕組みを利用するとアプリケーション内で保持するデータの変更をリアルタイムで取得することができ、 Angular のデータバインディングと組み合わせることで、データベースの最新データを常に画面に表示し続けることなどが簡単に実現できます。

firebase.google.com

Cloud Functions for Firebase

HTTP リクエストやスケジューラなどをトリガーとしてバックエンドコードを実行するサービスで、所謂 FaaS に分類されます。

Firebase における Cloud Functions の実行環境は Node.js ランタイムのみとなっており、対応言語は JavaScript か TypeScript になります。

サーバを意識せずにバックエンドコードを書けるというのは少人数のチームや小規模プロジェクトにとってメリットが大きく、今回は Web アプリケーションからの HTTP リクエストをトリガーとするメール送信や、後述する Cloud Scheduler での定期実行をトリガーとする API 連携などを実現しています。

また、 Cloud Functions (Node.js ランタイム) のバックエンドの実態は Express で構築されているため、送信したメール本文のリンクからのアクセス先として動的コンテンツを配信するなど、ちょっとした Web サーバのような使い方もできます。

firebase.google.com

Firebase Cloud Messaging

Firebase Cloud Messaging Backend を通してクライアントアプリケーションにメッセージを送信したり、クライアント側の SDK で受信したメッセージを表示することができるサービスです。

バックエンドコードを書かなくてもクライアントからクロスプラットフォームにメッセージの送信が行えるため、ブラウザの Angular アプリの処理をトリガーに Android アプリへプッシュ通知を送信することが可能です。

Web アプリの Service Worker の処理は firebase-messaging-sw.js というファイル名にする必要がありますが、ひと手間加えれば Angular/PWA の Service Worker の実体である ngsw-worker.js と併用することができ、 Angular が提供する Service Worker の機能をそのまま活かすことができます。

firebase.google.com

Google Cloud

Firebase も Google が提供するクラウドサービスですが、こちらが Google 本家のクラウドサービスになります。

今回のバックエンドのメインは Firebase ですが、提供元が同じ Google というだけあって Google Cloud の各製品と容易に連携することができます。

cloud.google.com

Cloud Pub/Sub

Publisher がトピックに対してメッセージを送信し、そのトピックを購読している Subscriber が非同期でメッセージを受信する、という Pub/Sub メッセージングモデルを実現するためのマネージドサービスです。

今回のアプリでは Gmail のメール受信時や Cloud Scheduler による定期実行でそれぞれ決められたトピックにメッセージを送信し、そのトピックを購読する Subscriber が Cloud Functions の処理を実行するという流れでいくつかの関数を実行しています。

cloud.google.com

Cloud Scheduler

cron 形式で指定したスケジュールに従い、トピックへのメッセージ送信や HTTP アクセスなどの予め決められた処理を実行するサービスです。

Cloud Scheduler → Cloud Pub/Sub → Cloud Functions と各サービスを連携させることで、Cloud Functions の定期実行を実現しています。

バックエンドコードを書いたら Firebase CLI で Cloud Functions のデプロイコマンドを実行するだけで上記構成を構築できるので、 Cloud Scheduler や Cloud Pub/Sub をほとんど意識することなく非常に簡単に実装することができます。

cloud.google.com

Secret Manager

Google Cloud で使用する API キーやパスワードなどの機密性の高いデータを、一元的に保存・管理するためのストレージサービスです。

今回は Cloud Functions からアクセスする外部サービスの API キーなどを保存するために使用しています。

cloud.google.com

Cloud Source Repositories

Google Cloud でホストされるプライベート Git リポジトリです。

ソースコードのバージョン管理を行うという目的においては必要十分なサービスになっていますが、 GitHub のような Pull Request や Issue の管理といった機能は無く、イマドキの Git ホスティングサービスと比較するとやや見劣りするというのは否定できません。

多分 Google さんも、このサービスにはあまり力を入れていないんじゃないかと思います…

cloud.google.com

Gmail

Gmail API

Gmail を操作するための API で、 JavaScriptPython などの様々な言語に対応しています。

今回は Gmail でのメール送信やメール受信時の Pub/Sub のトピックへのメッセージ送信など、主にバックエンドの処理で使用しました。

developers.google.com

開発環境・開発ツール

Windows 10 Pro の WSL2 上に Docker 環境を構築し、 Node.js の Docker イメージをベースとしたコンテナ内で開発を行いました。

開発ツールは今や高機能エディタのデファクトスタンダードになりつつある Visual Studio Code で、拡張機能を必要に応じて重くならない程度に入れています。

コードフォーマッターとリンターはそれぞれ Prettier と ESLint を使用しています。

Prettier については別記事で詳しく書いていますので、そちらをご覧ください。

ai-can-fly.hateblo.jp

そのうち ESLint についても自分用としてまとめたい…

おわりに

サーバレスという言葉が出て久しいですが、バックエンドをサーバレスで構築した初めてのアプリがこの Web アプリケーションでした。

これまでは誰かにサーバの構築を依頼して、その上に自分が開発したアプリケーションをデプロイするというのが常でしたが、要件さえ合致すればインフラエンジニアにはアドバイザーとしてスポット参戦してもらうだけでも、クラウドサービスを活用すれば何とかできなくもない状態になってきています。

環境構築やアプリケーションのデプロイも用意された CLI のコマンドだけで済む場合が多く、フロントエンド・バックエンドエンジニアにとっては本当に便利な世の中になりました…

これからもクラウドを活用して、フロントエンドからバックエンド、クラウドサービスを守備範囲とするフルスタックエンジニアとしてスキルを伸ばしていこうと思います。

ということで、今回紹介した事例のような開発を依頼、またはエンジニアを探している方はご連絡お待ちしています (๑´ڡ`๑)