0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPI入門 — PythonでREST APIをゼロから作る【初心者向け完全ガイド】

0
Posted at

はじめに

「PythonでAPIを作ってみたいけど、どこから始めればいいかわからない」

そんな方に向けて、FastAPI を使ってREST APIをゼロから構築する方法を丁寧に解説します。

FastAPIはPython製のWebフレームワークで、近年急速に普及しています。その理由は:

  • 高速:Starlette + Pydanticベースで、NodeやGoに匹敵するパフォーマンス
  • 型安全:Pythonの型ヒントを活かした自動バリデーション
  • 自動ドキュメント生成:コードを書くだけでSwagger UIが自動生成される
  • 学習コストが低い:シンプルで直感的なAPI設計

この記事では以下の内容をカバーします:

  1. 環境構築とインストール
  2. 最初のAPIを作る(GETリクエスト)
  3. POSTリクエストとリクエストボディの受け取り
  4. Pydanticによるバリデーション
  5. SQLiteとの連携(データの永続化)
  6. Swagger UIの活用

1. 環境構築とインストール

必要なもの

  • Python 3.8以上
  • pip(Pythonのパッケージマネージャー)

まずPythonのバージョンを確認しましょう。

python --version
# Python 3.11.x などと表示されればOK

仮想環境の作成(推奨というか必須)

プロジェクトごとにパッケージを管理するために、仮想環境を使います。

# プロジェクトフォルダを作成
mkdir fastapi-tutorial
cd fastapi-tutorial

# 仮想環境を作成
python -m venv venv

# 仮想環境を有効化
# macOS / Linux
source venv/bin/activate

# Windows
venv\Scripts\activate

FastAPIとuvicornのインストール

pip install fastapi uvicorn[standard]
  • fastapi:フレームワーク本体
  • uvicorn:FastAPIを動かすための高速ASGIサーバー

インストールが完了したら準備OKです!

2. 最初のAPIを作る(GETリクエスト)

Hello World

プロジェクトフォルダに main.py を作成します。

# main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

これだけです。たった5行でAPIサーバーが完成します。

サーバーの起動

uvicorn main:app --reload
  • mainmain.py のファイル名
  • app:FastAPIインスタンスの変数名
  • --reload:コード変更時に自動でリロード(開発時に便利)

ターミナルに以下のようなログが出れば成功です。

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process

ブラウザで http://127.0.0.1:8000 を開くと:

{"message": "Hello, FastAPI!"}

が表示されます。🎉

パスパラメータの受け取り

URLの一部を変数として受け取ることができます。

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}

http://127.0.0.1:8000/items/42 にアクセスすると:

{"item_id": 42}

Pythonの型ヒント int を付けるだけで、自動的に整数に変換・バリデーションしてくれます。文字列を渡すと自動でエラーを返してくれます。

クエリパラメータの受け取り

URLの ?key=value 形式のパラメータも簡単に受け取れます。

@app.get("/search")
def search_items(keyword: str, limit: int = 10):
    return {"keyword": keyword, "limit": limit}

http://127.0.0.1:8000/search?keyword=python&limit=5 にアクセスすると:

{"keyword": "python", "limit": 5}

limit: int = 10 のようにデフォルト値を設定することもできます。


3. POSTリクエストとリクエストボディ

GETはデータを取得するためのリクエストですが、POSTはデータを送信・作成するときに使います。

シンプルなPOSTエンドポイント

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float

@app.post("/items")
def create_item(item: Item):
    return {"message": "作成しました", "item": item}

Item クラスがリクエストボディのスキーマを定義しています。Pydanticの BaseModel を継承するだけで、自動的にJSONをPythonオブジェクトに変換してくれます。

curlでテスト

curl -X POST "http://127.0.0.1:8000/items" \
  -H "Content-Type: application/json" \
  -d '{"name": "りんご", "price": 150.0}'

レスポンス:

{
  "message": "作成しました",
  "item": {
    "name": "りんご",
    "price": 150.0
  }
}

4. Pydanticによるバリデーション

FastAPIの強力な機能のひとつが、Pydanticを使った自動バリデーションです。

バリデーションの基本

from pydantic import BaseModel, Field

class Item(BaseModel):
    name: str = Field(..., min_length=1, max_length=50, description="商品名")
    price: float = Field(..., gt=0, description="価格(0より大きい値)")
    stock: int = Field(default=0, ge=0, description="在庫数(0以上)")
    description: str | None = Field(default=None, description="商品説明(任意)")

Fieldのオプション:

オプション 意味
... 必須フィールド
min_length / max_length 文字列の長さ制限
gt / ge より大きい / 以上
lt / le より小さい / 以下
default デフォルト値

バリデーションエラーの確認

バリデーションに失敗した場合、FastAPIは自動的に 422 Unprocessable Entity を返してくれます。

# priceに負の値を送ってみる
curl -X POST "http://127.0.0.1:8000/items" \
  -H "Content-Type: application/json" \
  -d '{"name": "りんご", "price": -100}'

レスポンス:

{
  "detail": [
    {
      "type": "greater_than",
      "loc": ["body", "price"],
      "msg": "Input should be greater than 0",
      "input": -100
    }
  ]
}

エラー内容が詳細に返ってくるので、フロントエンドからも扱いやすいです。

レスポンスモデルの定義

レスポンスの形式も型で定義できます。

from pydantic import BaseModel

class ItemResponse(BaseModel):
    id: int
    name: str
    price: float

@app.post("/items", response_model=ItemResponse)
def create_item(item: Item):
    # DBに保存する処理(後述)
    return {"id": 1, "name": item.name, "price": item.price}

response_model を指定することで、余分なフィールドが自動的に除外され、ドキュメントにも反映されます。


5. SQLiteとの連携(データの永続化)

インメモリのデータはサーバー再起動で消えてしまいます。SQLiteを使ってデータを永続化しましょう。

必要なパッケージのインストール

pip install sqlalchemy

ファイル構成

fastapi-tutorial/
├── main.py
├── database.py    # DB接続設定
└── models.py      # テーブル定義

database.py(DB接続設定)

# database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

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

engine = create_engine(
    DATABASE_URL, connect_args={"check_same_thread": False}
)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

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

models.py(テーブル定義)

# models.py
from sqlalchemy import Column, Integer, String, Float
from database import Base

class ItemModel(Base):
    __tablename__ = "items"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, nullable=False)
    price = Column(Float, nullable=False)
    stock = Column(Integer, default=0)

main.py(全体を組み合わせる)

# main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel, Field
from database import engine, get_db, Base
from models import ItemModel

# テーブルを作成
Base.metadata.create_all(bind=engine)

app = FastAPI(title="商品管理API", version="1.0.0")


# Pydanticスキーマ
class ItemCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=50)
    price: float = Field(..., gt=0)
    stock: int = Field(default=0, ge=0)

class ItemResponse(BaseModel):
    id: int
    name: str
    price: float
    stock: int

    class Config:
        from_attributes = True  # SQLAlchemyモデルから変換を許可


# 商品一覧を取得
@app.get("/items", response_model=list[ItemResponse])
def get_items(db: Session = Depends(get_db)):
    items = db.query(ItemModel).all()
    return items


# 商品を1件取得
@app.get("/items/{item_id}", response_model=ItemResponse)
def get_item(item_id: int, db: Session = Depends(get_db)):
    item = db.query(ItemModel).filter(ItemModel.id == item_id).first()
    if item is None:
        raise HTTPException(status_code=404, detail="商品が見つかりません")
    return item


# 商品を作成
@app.post("/items", response_model=ItemResponse, status_code=201)
def create_item(item: ItemCreate, db: Session = Depends(get_db)):
    db_item = ItemModel(**item.model_dump())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item


# 商品を削除
@app.delete("/items/{item_id}", status_code=204)
def delete_item(item_id: int, db: Session = Depends(get_db)):
    item = db.query(ItemModel).filter(ItemModel.id == item_id).first()
    if item is None:
        raise HTTPException(status_code=404, detail="商品が見つかりません")
    db.delete(item)
    db.commit()

動作確認

# 商品を作成
curl -X POST "http://127.0.0.1:8000/items" \
  -H "Content-Type: application/json" \
  -d '{"name": "りんご", "price": 150, "stock": 100}'

# 一覧を取得
curl http://127.0.0.1:8000/items

# 1件取得
curl http://127.0.0.1:8000/items/1

# 削除
curl -X DELETE http://127.0.0.1:8000/items/1

6. Swagger UIの活用

FastAPIの最大の特徴のひとつが、コードを書くだけで自動的にAPIドキュメントが生成される点です。

アクセス方法

サーバーを起動した状態で以下のURLにアクセス:

  • Swagger UIhttp://127.0.0.1:8000/docs
  • ReDochttp://127.0.0.1:8000/redoc

Swagger UIでできること

  • 全エンドポイントの一覧表示:GETやPOSTなどHTTPメソッドごとに色分け
  • リクエスト・レスポンスの仕様確認:必須パラメータや型が一目でわかる
  • ブラウザ上でAPIを直接テスト:「Try it out」ボタンからリクエストを送れる
  • 自動的に最新状態を反映:コードを変更すると即座にドキュメントに反映

タイトルや説明を追加する

app = FastAPI(
    title="商品管理API",
    description="FastAPIで作ったシンプルな商品管理APIです。",
    version="1.0.0",
)

各エンドポイントにも説明を追加できます:

@app.get(
    "/items",
    response_model=list[ItemResponse],
    summary="商品一覧を取得",
    description="登録されているすべての商品を返します。",
)
def get_items(db: Session = Depends(get_db)):
    ...

まとめ

この記事では、FastAPIを使ったREST API開発の基本を一通り学びました。

学んだこと ポイント
環境構築 venv + pip install fastapi uvicorn
GETリクエスト パスパラメータ・クエリパラメータ
POSTリクエスト リクエストボディをPydanticモデルで受け取る
バリデーション Fieldオプションで細かい制約を設定
DB連携 SQLAlchemy + SQLiteでデータを永続化
Swagger UI /docs で自動生成されるドキュメントを活用

FastAPIはシンプルなコードで高機能なAPIを素早く構築できるフレームワークです。今回紹介した内容をベースに、認証(JWT)やDockerコンテナ化など、さらに発展的な内容にも挑戦してみてください!


💬 質問や感想があれば、コメント欄でお気軽にどうぞ!
👍 役に立ったら、いいね&ストックをお願いします!
🎓 ここまで読んでくださって、本当にありがとうございました!

参考リンク

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?