FastAPI Request Body 欄位驗證 (Body Field Validation)

就像 Query 和 Path 用於在函數參數中定義額外資訊,Pydantic 提供了 Field 類別,讓我們能在 Pydantic Model 內部對欄位進行同樣的設定。

導入 Field

from typing import Optional
from fastapi import FastAPI, Body
from pydantic import BaseModel, Field

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = Field(
        None, title="The description of the item", max_length=300
    )
    price: float = Field(..., gt=0, description="The price must be greater than zero")
    tax: Optional[float] = None

@app.put("/items/{item_id}")
async def update_item(
    item_id: int,
    item: Annotated[Item, Body(embed=True)]
):
    results = {"item_id": item_id, "item": item}
    return results

Field 的功能

Field 的運作方式與 Query, Path, Body 非常相似,它支援相同的驗證參數和元數據參數:

  1. 預設值:Field 的第一個參數是預設值。如果是必填欄位,使用 ... (Ellipsis)。
  2. 數值驗證:gt (大於), ge (大於等於), lt (小於), le (小於等於)。
  3. 字串驗證:min_length, max_length, pattern (取代舊版的 regex)。
  4. 文件描述:title, description (這些資訊會顯示在 Swagger UI 的 Schema 說明中)。

範例:詳細的 Model 定義

讓我們看一個包含完整驗證和文件的例子:

class Item(BaseModel):
    # 必填,字串
    name: str

    # 選填,預設為 None,最大長度 300,並提供文件標題
    description: Optional[str] = Field(
        None, title="The description of the item", max_length=300
    )

    # 必填 (使用 ...),必須大於 0,並提供描述
    price: float = Field(..., gt=0, description="The price must be greater than zero")

    # 選填,預設為 None
    tax: Optional[float] = None

當使用這個 Model 作為 Request Body 時,FastAPI 會:

  1. 驗證 price 是否大於 0。若否,回傳 422 錯誤。
  2. 驗證 description 長度是否小於 300。
  3. 在 /docs 文件頁面的 Schema 部分,顯示我們設定的 title 和 description。

總結

  • 使用 pydantic.Field 來宣告 Model 內部的欄位驗證規則。
  • 語法與 Query, Path 幾乎一致。
  • 這是讓你的 API 更加健壯且文件更友善的重要工具。