📂

Django を使用しているプロジェクトでのディレクトリ構造に関して考える

2022/12/23に公開

概要

  • 以前在籍した案件での技術的負債の解消の一環として掲題の取り組みをした
  • Github の issue にアップしていたが契約終了に伴って見れなくなるので別途残しておきたい → ここに移植

発生していた問題点

namespace の粒度にばらつきがある

  • サービス名の namespace があるのと同じ階層にリソース単位の namespace が切られている
    • 例えば、法人向けと消費者向けのサービスを提供してて各々をモノレポで管理しているとする
      • 法人向けの namespace が b2b だとしたら、これと同じ階層に company とか subscription みたいなリソースの namespace がある
      • → 「東京都・大阪府・新宿区」みたいな粒度のばらつきを感じる

レイヤー分けがされてない

  • 例えば modelsviews, serializers などの単位では分かれているがそれ以外に適当なレイヤーがない
    • → それに起因してか view にビジネスロジックが書かれたり責務が別れていないモジュールが跋扈して、分類に迷ったものはとりあえず utils に配置され治安が悪くなっている

ルーティング設定ファイルの肥大化

  • モノレポ構成なのに1つの urls.py に全部のプロジェクトのルーティングが集約されてしまっている
    • → 結果的に urls.py が肥大化して数千行単位になってしまっている

ディレクトリ構成の例示

前節の問題を解決できるように以下のように再考した

/
  - ◎ apps/  ※ 
    - settings.py
    - urls.py(各サービスの定義まとめる)
    - △ common/  ※ 汎用的なものをまとめるnamespace(サービスとフラット)
      - utils/
    - △ b2b  ※ サービスの粒度のnamespace
      - settings.py or __init__.py
      - urls.py (各機能の定義まとめる)
      - □ documents/  ※ 機能の粒度のnamespace (ドキュメントというリソースを管理するものをまとめる)
        - urls.py (ある機能での定義)
        - models/
        - views/
        - serializers/
        - migrations/
      - □ settings/  ※ 機能の粒度のnamespace(例えば設定機能)
        - ...
    - △ b2c/  ※ サービスの粒度のnamespace
      - ※ b2b と同じような構成とする
    - △ ...
  • ルート直下にサービスで名前空間切る

    • 各サービス共通で利用するものはこの階層で名前空間切る(core とか common とか適当な名前で)
  • サービス直下には機能毎の名前空間切る

    • それ以下に view とか model とかを配置
      • → △とか□とか記号が同じものは粒度が同じになるので namespace のばらつきは解消
  • apps直下の urls.py で各サービスのurlsをまとめる

    • → そしたら今みたいに urls.py が 1,000 行越えることもなくなってファイルが小さくなる

参考にしたOSS

https://github.com/gothinkster/django-realworld-example-app

https://github.com/alan2207/bulletproof-react

Discussion