基礎から学ぶPython入門 90日コース | 実践開発 - Day 82:プロジェクト設計

Python 90日で身につけるPython
スポンサーリンク
スポンサーリンク

Day 82:プロジェクト設計 ― 「コードを“家”として考えると、構造が見えてくる」

Day 82では、いよいよ 本格的なプロジェクト構成 を学びます。

今日のキーワードはこの7つ。

  • app
  • services
  • models
  • repositories
  • tests
  • config
  • main.py

これらは、Pythonで中規模〜大規模のアプリケーションを作るときに よく使われるディレクトリ構成です。

「なんだかフォルダが多くて難しそう…」 そんな気持ちがよぎるかもしれませんが、 ひとつひとつ丁寧に見ていくと、

「あ、役割ごとに分けているだけなんだ」

というシンプルな構造が見えてきます。

プロジェクト構成の全体像 ― 「家の間取り図」を描く

まずは、今日扱う構成をざっくり眺めてみましょう。

project/
├── app
├── services
├── models
├── repositories
├── tests
├── config
└── main.py

この構成は、 「役割ごとにフォルダを分けて、見通しを良くする」 という考え方がベースになっています。

家に例えるなら、

  • app は「玄関・リビング」
  • services は「キッチン(処理の中心)」
  • models は「設計図」
  • repositories は「倉庫(データの出し入れ)」
  • tests は「点検室」
  • config は「家の設定パネル」
  • main.py は「家の入り口」

というイメージです。

では、ひとつずつ丁寧に見ていきましょう。

app ― 「アプリケーションの入り口とルーティング」

appフォルダの役割

app は、 アプリケーションの“表側”を担当する場所 です。

FastAPIなら、

  • エンドポイント(APIのURL)
  • ルーティング
  • コントローラー的な役割

を置くことが多いです。

例:app/routes.py

# app/routes.py
from fastapi import APIRouter
from services.todo_service import get_tasks, create_task

router = APIRouter()

@router.get("/tasks")
def list_tasks():
    """
    タスク一覧を返すエンドポイント。
    """
    return get_tasks()


@router.post("/tasks")
def add_task(title: str):
    """
    タスクを作成するエンドポイント。
    """
    return create_task(title)
Python

ここでは、

  • APIのURL
  • リクエストを受け取る部分
  • services(後述)に処理を渡す部分

を担当しています。

重要ポイント:

app は「外からのリクエストを受け取る場所」。 実際の処理は services に任せる。

services ― 「ビジネスロジック(処理の中心)」

servicesフォルダの役割

services は、 アプリケーションの“頭脳” を置く場所です。

  • 計算
  • バリデーション
  • 複数の処理の組み合わせ
  • repositories との連携

など、アプリの中心となる処理をここにまとめます。

例:services/todo_service.py

# services/todo_service.py
from repositories.todo_repository import fetch_tasks, insert_task

def get_tasks():
    """
    タスク一覧を取得するサービス層の処理。
    """
    return fetch_tasks()


def create_task(title: str):
    """
    タスクを作成するサービス層の処理。
    """
    if len(title.strip()) == 0:
        raise ValueError("タイトルは空にできません")

    return insert_task(title)
Python

重要ポイント:

services は「アプリの中心となる処理」。 app(外側)と repositories(データ側)の橋渡し役。

models ― 「データの形(設計図)」

modelsフォルダの役割

models は、 データの構造を定義する場所 です。

  • SQLAlchemyモデル
  • Pydanticモデル
  • データクラス

などを置きます。

例:models/task.py

# models/task.py
from pydantic import BaseModel

class Task(BaseModel):
    """
    タスクのデータモデル。
    """
    id: int
    title: str
Python

重要ポイント:

models は「データの形」を表す。 アプリ全体で共通の“型”として使われる。

repositories ― 「データの出し入れ(倉庫)」

repositoriesフォルダの役割

repositories は、 データベースとのやり取りを担当する場所 です。

  • SELECT
  • INSERT
  • UPDATE
  • DELETE

など、データのCRUD処理をここにまとめます。

例:repositories/todo_repository.py

# repositories/todo_repository.py
import sqlite3

def fetch_tasks():
    """
    SQLiteからタスク一覧を取得する処理。
    """
    conn = sqlite3.connect("todo.db")
    cur = conn.cursor()
    cur.execute("SELECT id, title FROM tasks")
    rows = cur.fetchall()
    conn.close()

    return [{"id": r[0], "title": r[1]} for r in rows]


def insert_task(title: str):
    """
    SQLiteにタスクを追加する処理。
    """
    conn = sqlite3.connect("todo.db")
    cur = conn.cursor()
    cur.execute("INSERT INTO tasks (title) VALUES (?)", (title,))
    conn.commit()
    task_id = cur.lastrowid
    conn.close()

    return {"id": task_id, "title": title}
Python

重要ポイント:

repositories は「データベースとの会話担当」。 services が repositories を呼び出す構造が基本。

tests ― 「アプリの点検室」

testsフォルダの役割

tests は、 アプリの動作をチェックする場所 です。

pytestを使って、

  • 正常系
  • 異常系
  • エンドポイントのテスト
  • services のテスト

などを行います。

例:tests/test_todo.py

# tests/test_todo.py
from services.todo_service import create_task
import pytest

def test_create_task_normal():
    """
    正常系:タイトルが正しい場合は作成できる。
    """
    result = create_task("買い物")
    assert result["title"] == "買い物"


def test_create_task_empty():
    """
    異常系:タイトルが空の場合はエラーになる。
    """
    with pytest.raises(ValueError):
        create_task("")
Python

重要ポイント:

tests は「壊れていないか確認する場所」。 開発の安心感を支える大事なフォルダ。

config ― 「設定ファイルの置き場」

configフォルダの役割

config は、 アプリの設定をまとめる場所 です。

  • データベースの設定
  • APIの設定
  • 環境変数の読み込み
  • 共通設定

などを置きます。

例:config/settings.py

# config/settings.py
import os

DB_PATH = os.getenv("DB_PATH", "todo.db")
Python

重要ポイント:

config は「アプリ全体の設定を一箇所にまとめる場所」。

main.py ― 「アプリケーションの入り口」

main.pyの役割

main.py は、 アプリケーションのスタート地点 です。

FastAPIなら、

  • アプリケーションのインスタンス作成
  • ルーティングの読み込み
  • 実行の起点

などを担当します。

例:main.py

# main.py
from fastapi import FastAPI
from app.routes import router

app = FastAPI()

# ルーティングを登録
app.include_router(router)

# uvicorn main:app --reload で起動
Python

重要ポイント:

main.py は「アプリの玄関」。 ここから全てが始まる。

Day 82ミニテンプレート ― プロジェクト構成ひとまとめ

最後に、今日の内容をそのまま使える形でまとめます。

project/
├── app
│   └── routes.py
├── services
│   └── todo_service.py
├── models
│   └── task.py
├── repositories
│   └── todo_repository.py
├── tests
│   └── test_todo.py
├── config
│   └── settings.py
└── main.py

この構成は、 FastAPIやFlask、Djangoなど、 どんなフレームワークでも応用できます。

Day 82のまとめ ― 「プロジェクトは、役割ごとに部屋を分けると快適になる」

今日の主役は、

  • app:外側(ルーティング)
  • services:頭脳(ビジネスロジック)
  • models:設計図(データの形)
  • repositories:倉庫(データの出し入れ)
  • tests:点検室(テスト)
  • config:設定パネル
  • main.py:玄関(アプリの入り口)

でした。

プロジェクト構成を整えると、

  • コードが迷子にならない
  • 役割が明確になる
  • チーム開発がしやすくなる
  • 自分のコードに“プロジェクト感”が出てくる

という、たくさんのメリットがあります。

Day 82でこの構成を理解したことで、 これから作るアプリは、

「ただ動くだけじゃなく、整理されていて育てやすいもの」

へと、確実に進化していきます。

次のステップでは、この構成を使って 実際にプロジェクトを組み立てていきましょう。

タイトルとURLをコピーしました