CSR アーキテクチャ概要⚓︎
AlesInfiny Maia OSS Edition (以降、 AlesInfiny Maia)において、クライアントサイドレンダリング方式の Web アプリケーションを構築する際に想定しているアーキテクチャの概要について説明します。
技術スタック⚓︎
本アーキテクチャを構成する主なライブラリを以下に示します。
上の図で使用している OSS 製品名およびロゴのクレジット情報は こちら を参照してください。
利用ライブラリ(フロントエンド)
-
JavaScript を拡張して静的型付にしたプログラミング言語です。
-
シンプルな設計で拡張性の高い JavaScript のフレームワークです。
-
ES modules を利用してプロジェクトの高速な起動・更新を実現するフロントエンドビルドツールです。
-
Vue.js 用の状態管理ライブラリです。
-
Vue.js を利用した SPA で、ルーティング制御をするための公式プラグインです。
-
Vue.js で非同期通信を行うためのプロミスベースの HTTP クライアントです。
-
Vue.js 用のリアルタイムバリデーションコンポーネントライブラリです。
-
JavaScript でフォームのバリデーションルールを宣言的に記述できるライブラリです。
-
utility class を使って独自のボタンなどを作成する CSS フレームワークです。
-
JavaScript, Vue, CSS, JSON などのコードフォーマッターです。
-
JavaScript の静的検証ツールです。
-
CSS の静的検証ツールです。
-
Vite 環境で動作する高速なテスティングフレームワークです。
-
E2E テストツールです。
利用ライブラリ(バックエンド)
-
DI コンテナや AOP の機能を提供する Spring Framework のコアライブラリです。 ベースとなる Spring Framework のコアライブラリや、 Spring Framework の自動設定サポートを含む Spring Boot の機能を提供します。
-
Spring Framework をベースとするアプリケーション開発を効率的に行うためのフレームワークです。 Spring Framework の課題である煩雑な Bean 定義や設定ファイルを可能な限り自動設定したり、実装するコード量を軽減するアノテーションを提供します。
-
Spring MVC は Spring Framework をベースとする Front Controller パターンの Web MVC フレームワークです。
-
Spring Validation
Bean に対するデータの値チェック機能を提供するライブラリです。 アノテーションベースで汎用的に利用できる値チェックが提供され、入力値チェック等が簡潔に実現できます。
-
Spring Framework をベースとするアプリケーション実装をテストするためのライブラリです。 Unit Jupiter 、 Hamcrest 、 Mockito などのライブラリと連携して、テスト実装をサポートする機能を提供します。
-
Apache Log4j 2 は Java のロギングフレームワークです。 複数のロガーに対して、フィルター、ローテーション、ログレベルなどの細やかな管理ができます。
-
MyBatis はデータベースアクセスの実装に利用する O/R Mapper です。 XML ファイルまたはアノテーションに、 SQL やレコードとオブジェクトのマッピングを定義できます。
-
H2 Database は Java 上で動作するリレーショナルデータベースです。 単体テストやローカル環境でのアプリケーション実行など、ローカル環境でデータベースアクセスを含む動的テストを行うのに利用します。
-
OpenAPI 形式の Web API ドキュメントを生成するためのライブラリです。 Controller の実装から Web API ドキュメントを自動的に生成できます。 Web API ドキュメントの生成にあたり、 Controller の実装だけでは不十分な情報に関しては、アノテーションを利用して情報を付与できます。
アプリケーションアーキテクチャ⚓︎
AlesInfiny Maia のアプリケーションアーキテクチャは、クリーンアーキテクチャに基づいています。 アーキテクチャの全体概要は以下の通りです。
層の構造詳細⚓︎
クライアントサイドレンダリング方式の Web アプリケーションにおける、各層とそれを構成するコンポーネントの役割について、それぞれ説明します。
アプリケーションコア層⚓︎
アプリケーションコア層は、ドメインモデルの定義と業務処理を実装する業務中心の層です。
-
ドメインモデル
ドメインモデルは、業務で扱うドメインをクラスとして表現するエンティティと値オブジェクトで構成するコンポーネントです。 共にモデルのデータ構造と振る舞いを持つことは変わりませんが、エンティティはプロパティが可変である一方、値オブジェクトのプロパティは不変です。
-
ドメインサービス
ドメインサービスは、エンティティや値オブジェクトに含めることが適当ではないドメイン固有の処理を実装するコンポーネントです。 ドメイン単位でクラスにまとめ、ドメインに対する処理毎にメソッドとして実装します。 必要に応じてリポジトリを利用して、データベースなどの外部リソースにアクセスします。 アプリケーションコア層のリポジトリインターフェースを利用し、インフラストラクチャ層のリポジトリ実装に依存しないよう注意してください。
-
アプリケーションサービス
アプリケーションサービスは、システムに必要な機能を実装するクラスです。 1 つの Web API の業務処理がアプリケーションサービスの 1 メソッドに対応します。 エンティティや値オブジェクト、リポジトリ ( インターフェース ) を組み合わせて、必要な機能を実現します。 必要に応じてドメインサービスも利用します。
-
リポジトリ ( インターフェース )
アプリケーションコア層のリポジトリはインターフェースであり、インフラストラクチャ層のリポジトリで実装されます。 依存関係逆転の法則に従い、アプリケーションコア層の実装がインフラストラクチャ層に依存しないようするためのインターフェースです。
プレゼンテーション層⚓︎
プレゼンテーション層は、主にシステムの利用者とのやり取りを担う層です。 画面を構成するフロントエンドアプリケーションと、バックエンドアプリケーションのインターフェースとなる Web API を配置します。
-
コントローラー
コントローラーは Spring MVC のコントローラーに対応し、各 Web API の定義と実装を担います。 業務処理であるアプリケーションサービスを呼び出し、その結果からレスポンスデータを生成します。
-
API モデル
Web API のリクエスト/レスポンスの形式を定義するクラスです。 コントローラーが受け取る引数やレスポンスの型を Java のクラスで表現します。
-
ビュー
ビューは Vue.js の JavaScript アプリケーションとして実装します。
インフラストラクチャ層⚓︎
インフラストラクチャ層は、データベースを中心とする外部リソースにアクセスする処理を実現する層です。
-
リポジトリ
インフラストラクチャ層のリポジトリは、アプリケーションコア層のリポジトリインターフェースの実装クラスで、具体的なデータベースアクセス処理を実装します。 データベースとはテーブルエンティティの型を利用してデータをやり取りします。 それに対してリポジトリインターフェースはドメインモデルの型を用いて構成されています。 インフラストラクチャ層のリポジトリは、これらの型同士の変換処理を行う役割も持ちます。
-
テーブルエンティティ
テーブルエンティティはデータベースのテーブルに対応するデータ構造を表現するクラスです。 1 つのテーブルエンティティオブジェクトがテーブルの 1 レコードに対応します。
プロジェクト構成と各層とのマッピング⚓︎
AlesInfiny Maia では Java のプロジェクト構成として、複数のサブプロジェクトに分割し、それらをルートプロジェクトでまとめて管理するマルチプロジェクト構成を採用します。 サブプロジェクトの分割については、これまでに説明したアプリケーションコア層、プレゼンテーション層、インフラストラクチャ層の各層を 1 つのサブプロジェクトとして対応させることを推奨します。
どの層からも利用されるようなシステム共通機能については、依存関係からアプリケーションコア層に含める考えもありますが、こちらも独立したサブプロジェクトとすることを推奨します。 業務機能とシステム共通機能を分割することで、プロジェクトの役割や依存関係が明確になり、保守性が高まると考えられます。
各サブプロジェクトの内部構成については、以下のような構成を推奨します。
プロジェクト構造全体は、 Spring Initializr で生成した Gradle Groovy DSL プロジェクトの構造と変わりはありません。 パッケージの構成としては、システムで 1 つのフォルダー ( aa.bb.cc ) をベースに、各層に対応するパッケージ ( application-core など ) を作成します。 アプリケーションコア層については、ドメインの単位でパッケージを作成し、それ以外の層については、構成するコンポーネント単位でパッケージを作成することを想定しています。 以降の階層については、管理や機能面を考慮し、必要に応じてサブパッケージを作成してください。