🎄

FastAPIのディレクトリ構成の最適解を知りたいッッ!

2022/12/20に公開

記事を書いた背景

普段インターン先でFastAPIを用いたAPI構築業務をしている.
先日仲間とハッカソンに参加した際にFastAPIでバックエンド担当となったのだが、せっかく一から全てを自分で決めることができるということで、作り始める前にFastAPIでの最適なディレクトリ構成を探す旅に出た.今回は備忘録も兼ねて、旅の結果をここに書き留めておく.

FastAPIとは

FastAPI は、Pythonの標準である型ヒントに基づいてPython 3.6 以降でAPI を構築するための、モダンで、高速(高パフォーマンス)な、Web フレームワークです。
>>FastAPI公式

この記事の想定読者

  • FastAPIチュートリアルを読んだことがある人
  • 上記記事レベルの実装なら調べながらであればできる人
  • FastAPIで初めて中規模以上のアプリケーション開発を行う人
  • FastAPIで作成されたアプリケーションのメンテナンス性が悪くて困っている人

前提

今回の開発ではDockerは用いず、githubでの管理を前提としたディレクトリ構成となっている.
この記事はプログラムの内容面での話ではないのであまり関係ないかもしれないが、開発環境や各バージョン情報は以下の通り.

結論

いきなり結論だが、今回のハッカソン開発においての最適なディレクトリ構成図(全体像)は以下のようになった.

ディレクトリ構成図
app-backend/
├ src/
│ ├ assets/
│ │ └ //image-files
│ ├ crud/
│ │ ├ __init__.py
│ │ └ //crud-files
│ ├ database/
│ │ ├ seedings/
│ │ │ ├ __init__.py
│ │ │ └ //seeding-files
│ │ ├ __init__.py
│ │ ├ database.py
│ │ └ master_seeding.py
│ ├ routers/
│ │ ├ __init__.py
│ │ └ //routing-files
│ ├ schemas/
│ │ ├ __init__.py
│ │ └ //schema-files
│ ├ services/
│ │ ├ __init__.py
│ │ └ //service-files
│ ├ __init__.py
│ ├ dependencies.py
│ ├ main.py
│ └ models.py
├ tests/
│ ├ integration/
│ │ ├ __init__.py
│ │ └ //integration-test-files
│ ├ unit/
│ │ ├ __init__.py
│ │ └ //unit-test-files
│ ├ __init__.py
│ ├ conftest.py
│ └ dependencies.py
├ (.env)
├ .env.sample
└ .gitignore
# ()内表記は.gitignore対象.
# /で終わるものはディレクトリを表す.
# //で始まる表記は追加するファイルの内容を表す.

はい、今この図を見て気絶しそうになった人は、一旦意識を戻して次へ進もう.

この図は基本的にはディレクトリの構成図であるが、図中に記述してあるpythonファイル[*~.py]は、FastAPIアプリケーションとしての最小構成に必要なファイルとなっている.
以下ではそれぞれのディレクトリについて、"何がどう便利なのか"を詳しく説明していく.

1層目のディレクトリ構成

先ほどの図はディレクトリ構成図の全体像だったが、数が多くて見づらいため、まずは第1層から見ていこう.
app-backendディレクトリ直下だけを抜き出したのが以下の図である.

app-backend/
├ src/
├ tests/
├ (.env)
├ .env.sample
└ .gitignore
# /で終わるものはディレクトリを表す.

各ディレクトリ/ファイルについての詳細は以下の通り.

名称 type 詳細
src directory アプリのソースコード全般を格納.appという名称だったりもする.
tests directory アプリのテストコードファイルを格納.
.env ignore-file アプリ内で使用する環境変数を記述するファイル.このファイルにはクラウドサービスのシークレットキー等、外にもれたらとんでもないことになる情報を記述するため、GitHub上にはアップロードしない(.gitignoreファイルで指定する).
.env.sample file 先の.envファイルにおける入力が必要な"項目名"のみを記載するためのファイル.通常このファイルをGitHub上にアップロードし、クローン後に必要項目を記入して.envとリネームして使う.
.gitignore file このファイル内に記述したファイルorディレクトリはGitHub上にアップロードされなくなる(無視される).*でワイルドカードが使用できる.

2層目のディレクトリ構成

次に、第1層の各ディレクトリの内部構成をそれぞれ抜き出して解説していく.

srcディレクトリ

srcディレクトリ内では、アプリケーションのソースコードを記述していく.
srcディレクトリ内部のディレクトリ構成は以下の通り.

app-backend/
└ src/
  ├ assets/
  ├ crud/
  ├ database/
  ├ routers/
  ├ schemas/
  ├ services/
  ├ __init__.py
  ├ dependencies.py
  ├ main.py
  └ models.py
# /で終わるものはディレクトリを表す.
名称 type 詳細
assets directory アプリで使用する画像データなどを格納.
crud directory DBのcrud操作に関する処理を記述したファイルを格納.
database directory DB設定に関する処理を記述したファイルを格納.
routers directory ルーティング後のエンドポイントを記述したファイルを格納.
schemas directory データのスキーマ定義を行うファイルを格納.
services direvtory crud操作に関係のない関数を記述したファイルを格納.
__init__.py file __init__ファイルの使い方が分からない人はとりあえず作っておく.(今後この__init__.pyファイルは図中にのみ記載する.)
dependencies.py file 依存性注入に関する記述をしたファイルを格納.
main.py file エンドポイントに関する設定を行うファイル.このファイルがFastAPIアプリケーションの中心となる.
models.py file 今回はsqlalchemyというpythonのORMを行うことができるライブラリを使用したため、このファイル内でDBモデル設計を行う.

>>1層目のディレクトリ構成に戻る
>>2層目のディレクトリ構成に戻る

testsディレクトリ

testsディレクトリ内では、アプリケーションのテストコードを記述していく.
testsディレクトリ内部のディレクトリ構成は以下の通り.

app-backend/
└ tests/
  ├ integration/
  ├ unit/
  ├ __init__.py
  ├ conftest.py
  └ dependencies.py
名称 type 詳細
integration directory 主にアプリケーションの総合テストを記述したファイルを格納.
unit directory 主にアプリケーションの単体テストを記述したファイルを格納.
conftest file テストに関する設定や、各テストの事前/事後処理を記述するファイル.
dependencies.py file テスト時の依存性の上書きを定義する関数を記述するファイル.

>>1層目のディレクトリ構成に戻る
>>2層目のディレクトリ構成に戻る

3層目のディレクトリ構成

次に、3層目のディレクトリ構成のうち解説が必要なものだけを抜粋して説明する.

databaseディレクトリ

databaseディレクトリ内では、DB作成に必要なファイルや各種seedingに関するディレクトリ/ファイルを定義している.
databaseディレクトリ内部のディレクトリ構成は以下の通り.

app-backend/
└ src/
  └ database/
    ├ seedings/
    ├ __init__.py
    ├ database.py
    ├ db_handler.py
    └ data_handler.py
名称 type 詳細
seedings directory 作成したDBにseedingを行う処理を記述したファイル. 対象のテーブルごとにファイル分けした方が分かりやすい.
database file DBのengineやセッションの作成を行うファイル.
table_handler file DBのテーブル自体の生成/削除を行うためのファイル.
data_handler file 必要なデータやサンプルデータ等のInsert/Deleteを行うためのファイル.

何が便利なのか?

このディレクトリ構成は、アプリケーションのソースコードが肥大化してきたあたりから一気に効力を発揮する.自分が今触りたい処理はどこに記述してあるのかがディレクトリを辿っていくことですぐに行きつけるからである.
また、1ファイル当たりの記述量が少なくなったり、関係ない処理同士が同一ファイル内に存在しづらくなるなど、リファクタリングなどのメンテナンス性が高いという特徴もある.

まとめ

詳説が必要なディレクトリに関してここまで解説してきたが、ファイル内の実際の記述内容や各ファイルの繋がりまでは記載しきれなかったため、実際にFastAPIでの開発経験がある人以外には便利さがなかなか伝わりづらかったかと思う.
もし今後FastAPIでのアプリケーション開発をしてみたいという初学者の方は、今回紹介したこのディレクトリ構成を用いて簡単なアプリケーションを作成する手順を示した記事を書いているので、そちらも読みながらぜひ開発への第一歩を踏み出してほしい.

参考文献

Bigger Applications - Multiple Files (FastAPI公式)

Discussion