📚

🛠️ FastAPI 実践入門:第四歩目で学ぶCRUDとRESTful APIの設計

に公開

📦 はじめに

これまでのステップで、FastAPIの基礎的な使い方からテンプレートやセッションの扱いまでを学んできました。第四歩目では、いよいよFastAPIの真骨頂である「RESTful API設計」と「CRUD操作(データの作成・取得・更新・削除)」について詳しく解説します。
このステップを終える頃には、FastAPIを使って簡易的なデータベースアプリケーションのAPIを構築できるようになります。さらに、APIの設計指針やHTTPメソッドとの対応関係についても理解を深めることができるでしょう。これらの知識は、Webバックエンド開発において非常に重要な土台となります。

🧱 CRUDとは?

CRUDは、データベースを扱う上での基本的な4つの操作を指します:

  • Create(作成):新しいデータを追加する
  • Read(読み取り):データを取得する
  • Update(更新):既存のデータを変更する
  • Delete(削除):不要なデータを削除する

FastAPIでは、これらの操作をHTTPメソッド(POST、GET、PUT、DELETE)に対応させてAPIエンドポイントを構築することができます。これにより、明確で拡張性のあるWebサービスを提供することが可能です。

🧰 サンプルアプリの準備

📦 依存パッケージのインストール

以下のコマンドで必要なライブラリをインストールします:

pip install fastapi uvicorn sqlalchemy pydantic sqlite-utils

これでFastAPIとデータベース操作に必要なライブラリが整います。

📁 ディレクトリ構成

アプリケーション構成の一例を以下に示します:

project/
├── main.py         # APIエンドポイントの実装
└── models.py       # データベースモデルと設定

この構成により、機能ごとにコードを整理でき、保守性が高まります。

📌 データモデルの定義(models.py)

models.py
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "sqlite:///./test.db"

Base = declarative_base()
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(bind=engine)

class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String, index=True)

Base.metadata.create_all(bind=engine)

このコードでは、SQLiteを使ったシンプルなデータモデル Item を定義しています。SQLAlchemyを使うことで、データベース操作がPythonコードで柔軟に行えます。

🚀 APIエンドポイントの実装(main.py)

main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from models import Item, SessionLocal
from pydantic import BaseModel

app = FastAPI()

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

class ItemCreate(BaseModel):
    name: str
    description: str

# Create
@app.post("/items/")
def create_item(item: ItemCreate, db: Session = Depends(get_db)):
    db_item = Item(**item.dict())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item

# Read All
@app.get("/items/")
def read_items(db: Session = Depends(get_db)):
    return db.query(Item).all()

# Read One
@app.get("/items/{item_id}")
def read_item(item_id: int, db: Session = Depends(get_db)):
    item = db.query(Item).filter(Item.id == item_id).first()
    if item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

# Update
@app.put("/items/{item_id}")
def update_item(item_id: int, item: ItemCreate, db: Session = Depends(get_db)):
    db_item = db.query(Item).filter(Item.id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    db_item.name = item.name
    db_item.description = item.description
    db.commit()
    return db_item

# Delete
@app.delete("/items/{item_id}")
def delete_item(item_id: int, db: Session = Depends(get_db)):
    db_item = db.query(Item).filter(Item.id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    db.delete(db_item)
    db.commit()
    return {"message": "Item deleted"}

このコードでは、各CRUD操作をHTTPエンドポイントとして実装しています。Depends を使ってデータベースセッションを注入し、コードの再利用性と保守性を高めています。

🔄 RESTful設計のポイント

RESTfulな設計では、リソース(この場合は Item)を中心にURLとHTTPメソッドを対応させます。これにより、APIの構造が直感的になり、他の開発者にも理解しやすい設計となります。

操作 メソッド パス
作成 POST /items/
一覧取得 GET /items/
詳細取得 GET /items/{id}
更新 PUT /items/{id}
削除 DELETE /items/{id}

この設計は、APIドキュメント(Swagger UI)やクライアントサイドとの連携においても大きな利点があります。

🎯 まとめ

✅ CRUDはデータ操作の基本であり、FastAPIでシンプルに実装可能
✅ SQLAlchemyと組み合わせて堅牢なAPIを作成できる
✅ RESTfulな設計を意識することで、拡張性の高いWebアプリが実現
✅ Swagger UIでAPIの挙動を視覚的に確認可能


株式会社ONE WEDGE

【Serverlessで世の中をもっと楽しく】 ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
https://onewedge.co.jp/

Discussion