Pydantic 資料驗證與 OpenAPI
在上一章中,我們學會了如何建立一個簡單的 GET 路由。但是,在真實的商業應用中,我們最常處理的是客戶端傳送過來的 JSON 資料(例如:註冊表單、建立訂單、或是傳送一段文字給 AI 處理)。
這也就是 HTTP 的 POST 請求。
過去在 Flask 中處理 POST 請求,你必須手動從 request.json 中把欄位一個個拔出來,然後寫一堆又臭又長的 if / else 來檢查格式:
「名字有沒有填?」、「Email 格式對不對?」、「年齡是不是大於 0?」。
在 FastAPI 中,這些痛苦全都交給 Pydantic 來解決。
1. 什麼是 Pydantic?
Pydantic 是 Python 的一個資料驗證函式庫。它的核心概念是:使用 Python 原生的型別提示 (Type Hints) 來宣告資料結構。
你只需要定義一個「模型 (Model)」,FastAPI 就會在背後幫你做好所有事:
- 自動驗證:如果傳來的資料不符合模型,自動回傳 422 錯誤(附帶詳細的錯誤訊息)。
- 自動轉換:如果傳來的是字串
"123",但模型規定是int,它會自動幫你轉型。 - 自動產生文件:把這個模型同步到 Swagger UI 上,讓前端知道該傳什麼格式。
2. 建立你的第一個 Pydantic Model
讓我們來建立一個「新增會員」的 API。
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 等關聯式資料庫完美對接!