🐕

Flutterアプリ開発におけるフォルダ構成の考え方【バックエンド視点】

に公開

はじめに

バックエンド側の開発(特にDBやAPI)に数年携わっているので、ある程度慣れてきました。ただ、フロントエンドの経験は全くなく、Flutterは完全に独学です。
実際にアプリを作ろうとしたとき、最初に悩んだのが「フォルダ構成、どうしよう?」ということ。公式のテンプレートだとすべて lib/ 以下に詰め込まれていて、ちょっと整理しづらい…。ということで自分なりにフォルダ構成を考えてみました。

参考資料

以下の記事を参考にしました。
https://qiita.com/MLLB/items/95617322a7d984b7e402#comments
この記事では、1つの機能を1つのフォルダにまとめるアプローチが採用されていました。presentation層(画面)もその中に含めて管理されています。
アーキテクチャ、レイヤー構成は同じです。
自分としては同じ機能でも異なる画面で使いたいことがあると感じたため、presentation層だけ別で管理したかったのでpresentationとAPIで分けるような形にしました。

lib/
└── src/
    ├── api/
    │   ├── application/     // ユースケースやサービスの実装
    │   ├── domain/          // ユースケースのロジックなどの実装
    │   └── data/            // API通信やDBアクセスなどの実装
    │
    └── presentation/        // 画面やUIの定義

サンプルはこんな感じです。

lib/
└── src/                                 // アプリのソースコードを集約
    ├── api/                             // ビジネスロジック層
    │   ├── application/                 // ユースケースやサービスの実装
    │   │   ├── service/                 // serviceのインターフェース
    │   │   │   └── user_info.dart
    │   │   ├── dto/                     // service用の受け渡しデータクラス
    │   │   │   └── user_info_Dto.dart
    │   │   └── impl/                    // serviceの実装
    │   │       └── user_info_impl.dart
    │   │
    │   ├── domain/                      // ユースケースの中心となるロジック層(業務処理の要)
    │   │   ├── logic/                   // ドメインロジックのインターフェース
    │   │   │   └── userinfo/
    │   │   │       └── get_user_info_logic.dart
    │   │   ├── dto/                     // logic用の受け渡しデータクラス
    │   │   │   └── get_user_info_logic_dto.dart
    │   │   └── impl/                    // logicの実装
    │   │       └── get_user_info_logic_impl.dart
    │   │
    │   └── data/                        // データアクセス層
    │       ├── repository/              // repositoryインターフェース
    │       │   └── get_user_info_repository.dart
    │       ├── dto/                     // repository用の受け渡しデータクラス
    │       │   └── get_user_info_repository_dto.dart
    │       ├── impl/                    // repositoryの実装
    │       │   └── get_user_info_repository_impl.dart
    │       └── dao/                     // DBやAPIなど外部I/Oアクセスの定義
    │           └── get_user_info_repository_dao.dart
    │
    └── presentation/                    // 画面やUIに関するレイヤー
        ├── components/                  // 画面のパーツに相当するWidgetを配置(例:共通ボタン、ヘッダーなど)
        ├── controllers/                 // UIの状態管理に相当するコード(例:RiverpodのNotifierなど)
        └── screens/                     // 一画面を構成するWidget(ページ単位)

最後に

フォルダ構成はプロジェクトの進行やチームによって正解が変わるものだと思います。今回はFlutter初心者として、自分の経験をもとに「こうすれば管理しやすそう」と思った構成を模索しました。フロントエンド側の知識がほぼ0なので、こういったほうが管理しやすいとかあれば教えてほしいなと。。

Discussion