FastAPI ルーター管理 – 複数モジュールを効率的に構成する方法

目次

FastAPI ルーター管理 – 複数モジュールを効率的に構成する方法

ルーター管理の課題

FastAPI アプリケーションが成長するにつれて、エンドポイントの数も増えていきます。小さいうちは main.py にすべてのエンドポイントを書いても問題ありませんが、10 個、20 個、50 個のエンドポイントがあると、コード管理が大変になります。

今回は、複数のモジュールに分かれたエンドポイントを、効率的かつ保守性高く管理する「ルーター管理パターン」についてまとめておきたいと思います。

もしご自身で先に公式ドキュメントをご覧になられる方は下のリンクから眺めてみてください。
Bigger Applications – FastAPI ー 公式ドキュメント(英語)

対象となる方

  • FastAPI プロジェクトが成長中の方
  • 複数チームで開発している方
  • スケーラビリティを意識した設計を学びたい方

 ※ このドキュメントは FastAPI 0.141.1 以上で書いていきます。

3 つのルーター管理パターンの比較

パターン 1: main.py に全エンドポイント(スケーラビリティ最悪)

from fastapi import FastAPI

app = FastAPI()

# ドキュメント関連
@app.get("/api/documents")
async def list_documents():
    ...

@app.post("/api/documents")
async def create_document():
    ...

# ユーザー関連
@app.get("/api/users")
async def list_users():
    ...

# ... さらに 20+ エンドポイント

問題:

  • main.py が肥大化(数千行になる可能性)
  • 全員が main.py をいじるため git conflict が多発
  • エンドポイント一覧を把握しにくい
  • 責務分離ができていない

パターン 2: 自動スキャン(一見いいが危険)

import importlib
import pkgutil
from pathlib import Path

app = FastAPI()

modules_path = Path(__file__).parent / "modules"
for importer, modname, ispkg in pkgutil.iter_modules([str(modules_path)]):
    module = importlib.import_module(f"modules.{modname}")
    if hasattr(module, "router"):
        app.include_router(module.router, prefix="/api")

実際の問題:

  • 本当に登録されているか不明確
  • ファイルを削除しても登録解除できない可能性
  • デバッグ時に「どのモジュールが登録されてるのか」が見えにくい

パターン 3: リスト管理(ベストプラクティス)

from fastapi import FastAPI
from modules.documents.router import router as documents_router
from modules.users.router import router as users_router
from modules.projects.router import router as projects_router
from modules.tasks.router import router as tasks_router
from modules.comments.router import router as comments_router

app = FastAPI()

_routers = [
    ("documents", documents_router),
    ("users", users_router),
    ("projects", projects_router),
    ("tasks", tasks_router),
    ("comments", comments_router),
]

for _name, _router in _routers:
    app.include_router(_router, prefix="/api")

メリット:

  • main.py を開くだけで全機能が一覧できる
  • 新機能追加は「リストに 1 行追加」するだけ
  • 登録順序に依存しない
  • 明示的で安全

ベストプラクティス:モジュール構成

では、リスト管理パターンで使う、モジュールの実装例を見てみましょう。

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from core.auth import get_current_user, CurrentUser
from core.database import get_db
from . import service

router = APIRouter(tags=["documents"])

@router.get("/documents")
async def list_documents(
    user: CurrentUser = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    return await service.list_documents(db, user.id)

@router.post("/documents")
async def create_document(
    user: CurrentUser = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    return await service.create_document(db, user.id)

実装例:複数モジュールの追加

新しいモジュール「notifications(通知)」を追加する場合:

from modules.notifications.router import router as notifications_router

_routers = [
    ("documents", documents_router),
    ("users", users_router),
    ("projects", projects_router),
    ("tasks", tasks_router),
    ("comments", comments_router),
    ("notifications", notifications_router),  # ← ここに追加
]

for _name, _router in _routers:
    app.include_router(_router, prefix="/api")

新機能追加は「1 行」だけです。他は何も変更しません。

まとめ

以上で FastAPI のルーター管理パターンについて説明を終えたいと思います。

FastAPI プロジェクトが複数モジュールに分かれる場合は、「リスト管理パターン」を採用することで、スケーラビリティと保守性を大きく向上させられます。

10 個以上のエンドポイントがある場合は、モジュール分割 + リスト管理は「必須」と言ってもいいでしょう。チーム開発でも conflict が減り、各メンバーが独立して機能開発できるようになりますね ^^v 心がけよう!スケーラブルな設計!

ということで、ではまた〜

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Web Developer / Educator