---
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を開くと:
- 新しい
POST /users/ルートが表示されます。 - 開くと、Request Bodyに
username、email、age、is_activeが必要なことが明確に記載されています。 - "Try it out"をクリックし、意図的に
ageを送信しなかったり、ageを文字列"twenty"に設定したりすると、APIは即座にブロックし、どのフィールドに問題があるかを明確に示すJSONエラーメッセージを返します。
これがFastAPIの開発速度が驚異的に速い理由です!煩雑な入力チェックロジックを書く必要がなくなります!
3. 高度な検証:Field()の使用
単純な型宣言(例:strやint)だけでは不十分な場合があります。
パスワードの長さを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などのリレーショナルデータベースとシームレスに連携する方法を解説します!