green snake
Photo by Pixabay on Pexels.com

FastAPIとPydanticで始めるリクエスト・レスポンス定義ガイド


📋 記事のポイント(サマリー)

  • 誰向け?
    PythonとFastAPIの基礎は理解しているけれど、データのバリデーションや型安全なAPI設計を学びたい中級者さん
  • 学べること
    1. Pydanticモデル(BaseModel)の基本構造
    2. リクエストボディでのバリデーション方法
    3. レスポンスモデルによる出力制御・ドキュメント生成
    4. フィールドのデフォルト値・エイリアス・検証ルール設定
    5. ネストしたモデルやリスト、カスタムバリデータの活用例
  • 得られる効果
    • バリデーションエラーの自動生成で、堅牢かつ親切なAPIが実現できる
    • ドキュメントUIにモデル定義が反映され、フロント開発者との連携がスムーズに

🎯 対象読者

  • 学生エンジニアAさん(22歳)
    FlaskやDjangoで簡単なAPIは作ったことがあるものの、型ヒントや自動バリデーションの便利さを体感したい方
  • 社会人Bさん(30歳)
    社内向けツールのAPI設計をFastAPIに移行し、入力チェックや出力フォーマットを厳格化したいエンジニア
  • サイドプロジェクトCさん(27歳)
    趣味のToDoアプリで、安全にユーザー入力を受け取り、誰が見てもわかりやすいAPI仕様書を自動生成したい方

♿ アクセシビリティレベル

  • 読みやすさ:漢字・ひらがな・カタカナのバランスを配慮し、重要語には簡易ルビを併記
  • 構造化:見出し・サブ見出しと箇条書きで階層を明確化
  • コード例:コメント付きのコードブロックを幅固定で表示し、視認性を高める
  • ナビゲーション:各章末に「要点まとめ」を設け、スクリーンリーダーでも把握しやすい

1. Pydanticモデルの基本—BaseModelとは?

FastAPIが標準で採用する Pydantic は、Pythonの型ヒントを活用しつつ、データ検証とシリアライズを自動化してくれるライブラリです。
中心となるのは BaseModel クラスの継承で、各フィールドに型を指定するだけでバリデーションやデフォルト値の設定が可能になります。

from pydantic import BaseModel

class Item(BaseModel):
    name: str           # 必須の文字列
    price: float        # 必須の浮動小数点
    is_offer: bool = False  # オプション(デフォルト:False)

要点まとめ

  • BaseModel を継承してクラス定義
  • 型ヒントだけで検証・シリアライズが実行される
  • デフォルト値を指定すると「オプション」扱いに

2. リクエストボディでのモデル適用

2.1 FastAPIの引数にPydanticモデルを指定

POSTPUT のように、クライアントから JSON ボディを受け取る場合、エンドポイント関数の引数にPydanticモデルを型注釈するだけでOKです。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    is_offer: bool = False

@app.post("/items/")
async def create_item(item: Item):
    # itemはItemインスタンスとして受け取れる
    return {"item_name": item.name, "item_price": item.price}
  • クライアントが不正なJSONや型の値を送ると、自動的に 422 Unprocessable Entity エラーが返却されます。
  • レスポンスボディには、どのフィールドがどう間違っているかが詳細に含まれます。

要点まとめ

  • 関数引数にモデルを型注釈するだけでバリデーションが有効化
  • 不正入力時は自動的にエラーレスポンスを生成

3. レスポンスモデルでレスポンス制御

3.1 response_model パラメータの活用

エンドポイントの戻り値から、特定のフィールドのみを公開したい場合、response_model にモデルを指定します。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class ItemOut(BaseModel):
    name: str
    price_with_tax: float

@app.post("/items/", response_model=ItemOut)
async def create_item(item: ItemIn):
    price_with_tax = item.price * 1.1
    # 入力モデルから変換した出力モデルを返す
    return ItemOut(name=item.name, price_with_tax=price_with_tax)
  • レスポンスに含めたくない内部フィールドは除外でき、安全性が向上します。
  • 自動生成ドキュメントにも ItemOut の構造が反映され、API仕様が明確に。

要点まとめ

  • response_model で戻り値をモデル化
  • 不要なフィールドを自動でフィルタリング

4. フィールド設定の応用テクニック

4.1 Field で詳細設定

Pydanticの Field 関数を使うと、さらに細かな制約やメタデータを付与できます。

from pydantic import BaseModel, Field

class User(BaseModel):
    id: int = Field(..., ge=1, description="ユーザーID(1以上の整数)")
    name: str = Field(..., min_length=1, max_length=50)
    email: str = Field(..., regex=r'^\S+@\S+\.\S+$', description="有効なメールアドレス")
  • ...必須 を意味します。デフォルト値なしなら必ずクライアント提供が必要です。
  • ge, le, min_length, max_length, regex など、多彩なバリデーションが用意されています。
  • description はOpenAPIドキュメントに注釈として反映されます。

4.2 エイリアスと入力整形

外部APIやクライアント仕様でキー名がスネークケース以外の場合、alias オプションで対応可能です。

class Product(BaseModel):
    product_id: int = Field(..., alias="id")
    productName: str = Field(..., alias="name")

# クライアントは {"id":1,"name":"Book"} を送信
# 内部では product_id, productName プロパティでアクセスできる

要点まとめ

  • Field で制約とドキュメント注釈を追加
  • alias でJSONキー名とプロパティ名を切り分け

5. ネストモデル・リスト・カスタムバリデータ

5.1 ネストしたモデル

複雑なデータ構造でも、Pydanticモデルをネストして定義できます。

class Address(BaseModel):
    street: str
    city: str

class UserProfile(BaseModel):
    name: str
    address: Address  # ネストモデル

@app.post("/profiles/")
async def create_profile(profile: UserProfile):
    return profile

5.2 リスト型フィールド

複数要素を受け取る場合はリストで型指定します。

class Tag(BaseModel):
    name: str

class Article(BaseModel):
    title: str
    tags: list[Tag]  # Tagモデルのリスト

5.3 カスタムバリデータ

独自のチェックが必要な場合、@validator デコレータでメソッドを定義できます。

from pydantic import validator

class Order(BaseModel):
    quantity: int
    @validator("quantity")
    def must_be_positive(cls, v):
        if v <= 0:
            raise ValueError("quantity must be positive")
        return v

要点まとめ

  • ネストやリストで複雑な構造を簡潔に表現
  • @validator で自由なバリデーションが可能

6. まとめと次のステップ

本記事では、Pydanticモデルによるリクエスト・レスポンス定義の核心部分をカバーしました。

  • BaseModel を継承してモデルを作成
  • リクエスト引数や response_model で適用するだけのシンプルさ
  • Fieldaliasvalidator で柔軟かつ厳密な制約設定
  • ネストモデルやリストで実用的なデータ構造を実現

これらをマスターすると、FastAPIの自動ドキュメントや型安全性を最大限に活かした堅牢なAPI設計が可能になります。
次のステップとしては、データベース連携や認証機能と組み合わせて、さらに実践的なサービス構築に挑戦してみてくださいね♡

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)