Create Branch

個人プロダクトのモノレポプロジェクト全体像について

Published on 2025年4月7日

メモ

はじめに

個人プロダクトのアーキテクチャ設計を進めいている段階です。 基本的にフロントエンドエンジニアとしてフロント設計に比重を起きつつ、バックエンドもモダン開発環境で進めていくために、色々な記事を見たり、現在就業している企業のアーキテクチャを参考にして、どこに強みがあり、何を基準に選定しているかを認識しながら進めていきました。

現在の構成

本格的な開発を行うまでは、以下のような構成でした。

この段階では、repositoryをどのように構成するか全く考えてなく、Next.jsにそのまま乗っけているような形でした。


├── app/                     # Next.js App Router
├── packages/
│   ├── ui/                  # UIコンポーネント
│   └── database/            # データベース関連


この構成は単純ですが、バックエンドロジックとフロントエンドの境界が不明確な状態であり、このまま実装していくと、様々なものに依存関係を持つことなると思い、しっかりと設計することにしました。

この時点での課題

  1. バックエンドロジックとフロントエンドの切り分けがディレクトリを見た時にわからない。
  2. ロジックとデータベースに依存関係が発生する。
  3. 責任分離の不明確さ

設計思想

前提として、サービス運用を行う中で保守運用作業が発生します。

この時に、

  1. 依存関係を各レイヤー発生すると、複雑な状態となりコストがかかる。
  2. いつでも使用している技術を捨てて、他の技術に乗り換えれるようにする。

上記を解決するためには、各レイヤーの依存関係を持たせないことに重点を置いています。

これらの課題を解決するために、BFFパターンとオニオンアーキテクチャを導入することにしました。

新しいアーキテクチャの設計


├── apps/                     
│   ├── api-server     # apiとして機能す
|   |                    -> Next.jsのapp routerをAPI Routerとして使用
│   └── beatfolio      # エンドユーザー・プレイヤー使用するアプリケーション
│            └── api   # BFF層
├── packages/
│   ├── ui/                   # UIコンポーネント
│   ├── database/             # データベース関連
│   ├── domain/               # ドメイン層
│   │   ├── src/
│   │   │   ├── entities/     # ドメインエンティティ
│   │   │   └── repositories/ # リポジトリインターフェース
│   │   └── package.json


BFFパターンの採用

Backend for Frontend(BFF)パターンは、フロントエンドとバックエンドの間に中間層を設けるアプローチです。BFFの主な責務としては下記があります。

  • リクエスト・レスポンスの変換
  • 認証・認可の処理
  • フロントエンド固有のデータ形式への変換

本プロジェクトでは、apps/beatfolio/apiディレクトリがこのBFF層として機能します。

各層の役割と依存関係

1. UI層 (beatfolio)

  • 役割: ユーザーインターフェースの提供、ユーザー操作の処理
  • 依存: Fetcher層のみに依存し、BFFやAPIに直接依存しない
  • 利点:
    • データ取得のロジックに依存しないことでUIのみに責務を置くことができます。

2. Fetcher層

  • 役割: データ取得の抽象化
  • 依存: BFF層のAPIを実行するため、BFFに依存している状態
  • 利点:
    • UIからデータ取得ロジックを分離

3. BFF層 (beatfolio/api)

  • 役割: フロントエンド特化APIの提供、データ変換・集約
  • 依存: API層(api-server)に依存
  • 処理:
    • api-serverから複数APIエンドポイントを実行して、UI向けデータ形式への変換

4. API層 (api-server)

  • 役割: ビジネスロジックの実行、データの永続化
  • 依存: データベース、外部サービス

オニオンアーキテクチャの採用

オニオンアーキテクチャは、ソフトウェアの構造を「層」として表現し、依存関係が外側から内側に向かう(内側の層は外側の層に依存しない)ようにするアーキテクチャパターンです

  1. ドメイン層(中心):ビジネスエンティティとルール
  2. サービス/ユースケース層:アプリケーション固有のビジネスロジック
  3. インフラストラクチャ層:データベースアクセスなどの技術的実装
  4. UI/API層(外側):ユーザーインターフェースとAPI

このアーキテクチャは、ビジネスルールをアプリケーションの中心に置き、技術的な実装の詳細から保護されます。
システムを構築する技術とビジネスロジックを自体に依存関係を持たせない状態を作ること目指しています。

システムで使用する実装がビジネスロジックを呼び出して使う側にすることにより、実装からビジネスロジックを守り、ビジネスロジック自体に技術的な依存関係を持たせないようします。
詳しくは書籍などで学習してみてください。

下記が過去に勉強のため、作成したDDDを用いたオニオンアーキテクチャのディレクトリです。
https://github.com/hirayamahiroto/leran-ddd

下記が参考となる記事です。

https://qiita.com/k_yamaki/items/bf99d3bf64a84258a3a1

まとめ

このアーキテクチャ設計のは出発点であり、プロジェクトの成長に応じて変化させていく必要があります。

プロジェクト進行の都合上、最初からこの形を目指せるわけではありませんので、実装をしつつ技術負債を解消していけるように、サイクルを回りしていきたいと考えております。

参考

最終的なアーキテクチャは下記のようになります。

hirotobeat