【クリーンアーキテクチャ×FastAPI】ファイル・フォルダ構成について考える。

こんにちは、にわこまです!

今回は、クリーンアーキテクチャを採用したFastAPIアプリケーションのファイル・フォルダ構成について考えてみました。

最近は、生成AIにソースコードを作成させることがほとんどだと思います。その際のインプットとしていただくことでより精度の高いソースコードが生成されるのではないかと思います。

ぜひ参考にしてみてください。

 

 

スポンサードサーチ


ファイル・フォルダ構成

Googleスプレッドシートに一覧をまとめています。
ファイル・フォルダ構成
自由にダウンロードしていただいて問題ないです。

src
├─ application
│   ├─ usecases
│   ├─ dto
│   ├─ mappers
│   ├─ interfaces
│   ├─ transaction
│   │   └─ unit_of_work.py
│   └─ exceptions
├─ domain
│   ├─ entities
│   ├─ value_objects
│   ├─ services
│   ├─ exceptions
│   └─ constants
├─ infrastructure
│   ├─ database
│   │   ├─ common
│   │   │   └─ retry_manager.py
│   │   └─ xxx
│   │       ├─ repositories
│   │       ├─ models
│   │       ├─ session.py
│   │       ├─ engine.py
│   │       ├─ mappers
│   │       └─ transaction.py
│   ├─ external
│   │   ├─ common
│   │   │   └─ retry_manager.py
│   │   └─ xxx
│   │       ├─ client.py
│   │       ├─ dto
│   │       │   ├─ xxx.py
│   │       │   └─ yyy.py
│   │       └─ mapper.py
│   └─ messaging
│        ├─ xxx_producer.py
│        ├─ xxx_consumer.py
│        └─ yyy_producer.py
├─ presentation
│   ├─ routers
│   ├─ requests
│   ├─ responses
│   ├─ mappers
│   ├─ exception_handlers
│   └─ deps.py
├─ shared
│   ├─ exceptions
│   ├─ logging
│   ├─ config
│   └─ utils
└─ main.py

 

前提

  • 使用言語が Python であること。
  • REST API アプリケーションであること。
  • 実処理では、DBとのやり取りや他サービスとのやり取りを想定すること。
  • 小規模から中規模であること。※多くとも20APIくらい。
  • クリーンアーキテクチャを採用すること。特に依存性の方向を守ること。以下、図に示す。
  • FastAPIを採用すること。

 

依存性の方向

flowchart TB

    Presentation["Presentation"]
    Application["Application"]
    Domain["Domain"]

    Infrastructure["Infrastructure"]

    Presentation --> Application
    Application --> Domain

    Infrastructure --> Application
    Infrastructure --> Domain


    style Presentation fill:#A2FDBA
    style Application fill:#FFA09C
    style Domain fill:#FCFDB9
    style Infrastructure fill:#A7D7FD
自分\相手PresentationApplicationDomainInfrastructure
Presentation依存する。依存しない。依存しない。
Application依存しない。依存する。依存しない。
Domain依存しない。依存しない。依存しない。
Infrastructure依存しない。依存する。依存する。
  • Presentation層はApplication層に依存する。
  • Application層はDomain層に依存する。
  • Domain層は他の層に依存しない。
  • Infrastructure層はApplication層(interfaces)に依存する。
  • Infrastructure層はDomain層に依存する。

 

責務

責務説明
PresentationHTTPの責務エンドポイント、リクエストボディ、レスポンスボディを定義する。Open APIに記載した内容を定義するイメージ。
Application業務フローの責務何をどの順番で実行するか定義する。
Domain業務ルールの責務他技術に依存しない業務に関するデータや処理を定義する。
Infrastructure技術的実装の責務データベースやREST API、Kafkaなどの外部との連携を定義する。
Sharedアプリ内共通、業務仕様に依存しないロガーや定数を定義する。他の層から共通的に使用される処理を定義する。

 

Presentation

エンドポイント、リクエストボディ、レスポンスボディを定義する。

ファイル・フォルダ責務説明
presentation/routersルータの実装Open APIの仕様に基づきエンドポイントを定義し、UseCaseを呼び出す。
presentation/requestsリクエストボディの定義Open APIの仕様に基づきリクエストボディを定義し、バリデーションを行う。
presentation/responsesレスポンスボディの定義Open APIの仕様に基づきレスポンスボディを定義する。
presentation/mappersデータの変換リクエストボディやレスポンスボディをApplicaiton層のDTOに変換する処理を実装する。
presentation/exception_handlers例外のハンドリングApplication層の例外やDomain層の例外をHTTPレスポンスへ変換する。
presentation/deps.pyDIの実装UseCaseやRepositoryなどの依存関係を解決し、オブジェクトを組み立てる。

 

Application

何をどの順番で実行するか定義する。

ファイル・フォルダ責務説明
application/usecasesユースケースの実装業務処理の流れを実装する。トランザクション境界の管理やRepositoryの呼び出しを行う。
application/dtoDTOの定義Application層で使用するデータクラスを定義する。
application/mappersデータの変換Application層のDTOからDomain層のEntityに変換する処理を実装する。
application/interfacesインターフェースの定義Infrastructure層が実装するRepositoryや外部サービスClientのインターフェースを定義する。
application/transaction/unit_of_work.pyUnitOfWorkの実装複数RepositoryのCommitやRollbackを管理し、トランザクション境界を提供する。
application/exceptions例外の定義UseCaseで発生する業務処理上の例外を定義する。

 

Domain

他技術に依存しない業務に関するデータや処理を定義する。

ファイル・フォルダ責務説明
domain/entitiesエンティティの定義一意性を持つ業務オブジェクトを定義する。状態遷移や業務ルールを保持する。
domain/value_objects値オブジェクトの定義不変オブジェクトを定義する。入力値の妥当性や業務上の制約を保証する。
domain/servicesサービスの実装特定のEntityやValue Objectだけでは表現できない業務ロジックを実装する。
domain/exceptions例外の定義業務ルール違反や不正な状態を表す例外を定義する。
domain/constants定数の定義状態値や業務ルール、Domain層で使用する定数を定義する。

 

Infrastructure

データベースやREST API、Kafkaなどの外部との連携を定義する。

ファイル・フォルダ責務説明
infrastructure/databaseデータベース関連の機能を定義データベースとの接続や永続化処理を実装する。
infrastructure/database/common共通機能を定義複数データベースで共通利用する技術的な機能を定義する。
infrastructure/database/common/retry_manager.pyリトライ機能を定義デッドロックや一時的な接続障害などに対するリトライ処理を実装する。
infrastructure/database/xxx個別のデータベース関連の機能を定義接続先データベースごとの機能を実装する。
infrastructure/database/xxx/repositoriesリポジトリの実装Application層で定義したRepositoryインターフェースを実装する。
infrastructure/database/xxx/modelsテーブルを定義SQLAlchemy等で使用するORMモデルやテーブルを定義する。
infrastructure/database/xxx/session.pyセッション管理機能を定義SQLAlchemy Sessionの生成・取得・破棄など、セッションライフサイクルを定義する。
infrastructure/database/xxx/engine.pyデータベース接続の実装SQLAlchemy Engineの生成や接続プール設定など、DB接続設定を定義する。
infrastructure/database/xxx/mappersデータの変換Domain層EntityとDB Modelの相互変換を実装する。
infrastructure/database/xxx/transaction.pyトランザクション管理機能を定義トランザクション開始・コミット・ロールバックなどの制御を実装する。
infrastructure/external外部サービス連携の機能を定義外部サービスとのHTTP通信を実装する。
infrastructure/external/common共通の定義外部サービス共通で利用する技術的な機能を定義する。
infrastructure/external/common/retry_manager.pyリトライ機能を定義タイムアウトや一時的な通信障害などに対するリトライ処理を実装する。
infrastructure/external/xxx個別サービス関連の機能を定義外部サービスごとの機能を実装する。
infrastructure/external/xxx/client.pyAPIクライアントの定義HTTP通信を定義する。
infrastructure/external/xxx/dtoDTOの定義外部サービスとの通信で使用するDTOを定義する。
infrastructure/external/xxx/dto/xxx.pyAPIごとのDTOの定義XXX APIのリクエストボディやレスポンスボディを定義する。
infrastructure/external/xxx/dto/yyy.pyAPIごとのDTOの定義YYY APIのリクエストボディやレスポンスボディを定義する。
infrastructure/external/xxx/mapper.pyデータの変換Domain層のEntityと外部API DTOの相互変換を行う。外部APIの仕様変更をDomain層へ波及させない責務を持つ。
infrastructure/messagingKafka関連の機能を定義Kafkaの送受信機能を実装する。
infrastructure/messaging/xxx_producer.pyTopicごとのProduerを定義XXX TopicのProducerを実装する。
infrastructure/messaging/xxx_consumer.pyTopicごとのConsumerを定義XXX TopicのConsumerを実装する。
infrastructure/messaging/yyy_producer.pyTopicごとのProduerを定義YYY TopicのProduserを実装する。

xxxyyyは、データベースごとやAPIごと、Topicごとを表現しています。

上記ファイル・フォルダ構成には記載していませんが、messagingフォルダ配下にdtomappersがあってもよいと思います。以下にイメージを示します。

messaging
├─ xxx_producer.py
├─ xxx_consumer.py
├─ yyy_producer.py
├─ dto
└─ mappers

 

Shared

ロガーや定数を定義する。他の層から共通的に使用される処理を定義する。

ファイル・フォルダ責務説明
shared/exceptions共通例外共通利用する例外クラスを定義する。
shared/loggingLoggerの管理Loggerの設定を定義する。
shared/config設定値の管理環境変数の読み込みや共通的に使用する定数を定義する。
shared/utils共通ユーティリティ日付変換や文字列操作などの共通処理を実装する。

 

main.py

ファイル・フォルダ責務説明
main.pyアプリケーションの起点FastAPI起動。Exception Handlerの設定。Lifespanの設定。Routerの登録。

 

 

まとめ

今回は、クリーンアーキテクチャを採用したFastAPIアプリケーションのファイル・フォルダ構成について考えてみました。

ここまで考えてみて、FastAPIである必要性はないなと思いました笑。Flaskでも問題ないと思いました。

Googleスプレッドシートに一覧をまとめています。
ファイル・フォルダ構成
自由にダウンロードしていただいて問題ないです。

かなり、具体例を示せたと思っています。ゆえに、ご自身の既存のファイル・フォルダ構成と異なる点があると思います。

その際は、メールまたはX(Twitter)でご意見いただければと思います。

 

最後までお読みいただきありがとうございます。


スポンサードサーチ