---
title: "Pydantic データ検証と OpenAPI"
description: "JSONフォーマットを手動でチェックする必要はもうありません!Pydanticの強力な機能を深く掘り下げ、ハッカーの悪意ある攻撃や誤ったデータフォーマットを自動的にブロックしましょう。"
order: 2
---

# Pydantic データ検証と OpenAPI

前章では、シンプルなGETルートの作成方法を学びました。しかし、実際のビジネスアプリケーションでは、クライアントから送信されるJSONデータ(例:登録フォーム、注文作成、AI処理用のテキスト送信)を扱うことが最も一般的です。

これがHTTPの**POST**リクエストです。

FlaskでPOSTリクエストを処理する場合、`request.json`からフィールドを一つずつ取り出し、「名前は入力されているか?」「Emailのフォーマットは正しいか?」「年齢は0より大きいか?」といった長く煩雑な`if / else`チェックを書く必要がありました。

FastAPIでは、これらの苦痛をすべて**Pydantic**に任せることができます。

## 1. Pydanticとは?

PydanticはPythonのデータ検証ライブラリです。その核心理念は、**Pythonネイティブの型ヒント(Type Hints)を使用してデータ構造を宣言する**ことです。

「モデル(Model)」を定義するだけで、FastAPIが裏ですべてを処理します:
1. **自動検証**:送信されたデータがモデルに合致しない場合、422エラーを自動返信(詳細なエラーメッセージ付き)。
2. **自動変換**:文字列`"123"`が送信されても、モデルが`int`と規定していれば自動的に型変換。
3. **自動ドキュメント生成**:このモデルをSwagger UIに同期させ、フロントエンドがどのフォーマットで送信すべきかを明確にします。

## 2. 最初のPydanticモデルを作成

「新規会員登録」APIを作成してみましょう。

```python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# 1. Pydanticモデルを宣言
class UserCreate(BaseModel):
    username: str
    email: str
    age: int
    is_active: bool = True  # デフォルト値を提供

# 2. ルートでこのモデルをパラメータとして使用
@app.post("/users/")
async def create_user(user: UserCreate):
    # この時点で、送信されたuserは厳密に検証済みのオブジェクトです!
    print(f"新規ユーザー受信:{user.username}, メール:{user.email}")
    
    # データベース書き込みをシミュレート
    user_dict = user.model_dump() # モデルを辞書に変換
    user_dict["user_id"] = 9527
    
    return {"message": "会員登録成功", "data": user_dict}

このAPIをテスト

http://127.0.0.1:8000/docsを開くと:

  1. 新しいPOST /users/ルートが表示されます。
  2. 開くと、Request Bodyにusernameemailageis_activeが必要なことが明確に記載されています。
  3. "Try it out"をクリックし、意図的にageを送信しなかったり、ageを文字列"twenty"に設定したりすると、APIは即座にブロックし、どのフィールドに問題があるかを明確に示すJSONエラーメッセージを返します。

これがFastAPIの開発速度が驚異的に速い理由です!煩雑な入力チェックロジックを書く必要がなくなります!

3. 高度な検証:Field()の使用

単純な型宣言(例:strint)だけでは不十分な場合があります。 パスワードの長さを8文字以上に制限したり、年齢を18歳から100歳の間に制限したり、商品価格を負数にできないようにしたい場合があります。

このような場合、Fieldをインポートして詳細な検証を行います:

from pydantic import BaseModel, Field, EmailStr

class ProductCreate(BaseModel):
    name: str = Field(..., min_length=2, max_length=50, description="商品名")
    price: float = Field(..., gt=0, description="商品価格(0より大きい必要があります)")
    discount: float | None = Field(default=None, ge=0, le=1, description="割引率(0.0~1.0)")
    tags: list[str] = Field(default_factory=list, max_items=5)

解説:

  • Field(...)...はこのフィールドが必須(Required)であることを示します。
  • gt=0:Greater Than(0より大きい必要があります)。
  • ge=0, le=1:Greater or Equal to 0, Less or Equal to 1(0%から100%の割引に使用)。
  • description:この説明はSwagger APIドキュメントに直接レンダリングされ、フロントエンドエンジニアが一目で理解できます!

[!TIP] Email検証の神器 Emailフォーマットを検証する場合、複雑な正規表現(Regex)を自分で書く必要はありません。email-validatorパッケージをインストール(pip install email-validator)し、型をEmailStrと宣言するだけで、Pydanticが自動的にフォーマットをチェックします!

4. ネストされたモデル(Nested Models)

実際のAPIでは、JSONが複数層になることがよくあります。Pydanticでは、モデルの中にモデルを包むだけで簡単に処理できます:

from pydantic import BaseModel

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

class UserProfile(BaseModel):
    name: str
    address: Address  # 別のモデルを型として直接使用

@app.post("/profile/")
async def update_profile(profile: UserProfile):
    return {"city": profile.address.city}

5. まとめ

Pydanticは、バックエンドAPIの「最強の門番」のような存在です。汚れたデータ、誤ったデータ、悪意のあるデータはすべて、ビジネスロジックに到達する前にPydanticによってブロックされます。

データの純度が確保されたら、次はこれらのデータを実際に「ハードディスクに書き込む」段階です。次章では、Python最強のORMシステム——SQLAlchemyを紹介し、PostgreSQLなどのリレーショナルデータベースとシームレスに連携する方法を解説します!

完全なチュートリアルをロック解除

このチャプターは有料コンテンツです。プロジェクトに参加して、10以上の神レベルのPromptや実際のソースコード例を含む、5000字以上の深い分析をロック解除してください!