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

就像 QueryPath 用於在函數參數中定義額外資訊,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 部分,顯示我們設定的 titledescription

總結

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