這篇文章將會教你如何在 FastAPI 中宣告並讀取路徑參數 (Path Parameters),你將學會如何透過 URL 傳遞變數給伺服器,實現取得特定用戶資料或商品資訊等功能。
什麼是路徑參數?
路徑參數是 URL 網址結構的一部分,用來識別特定的資源或資料,想像你去圖書館找書,書架上的分類標籤(例如 /books/harry-potter)就是路徑參數,它告訴系統你要拿哪一本特定的書,而不是整櫃的書。在 FastAPI 中,我們使用 Python 的 f-string 語法 {parameter_name} 來宣告它。
路徑參數基礎概念
1. 基礎宣告與接收
要在路徑中定義參數,只需將變數名稱放在{} 中,並在函式參數中接收它。FastAPI 會自動將 URL 中的對應部分解析為字串並傳入函式。from fastapi import FastAPI
app = FastAPI()
@app.get("/articles/{article_id}")
def get_article(article_id):
return {"article_id": article_id}
當用戶訪問 /articles/01 時,FastAPI 會擷取字串 01 並將其賦值給參數 article_id,最後回傳 JSON 結果。
2. 型別驗證與轉換
利用 Python 的型別提示 (Type Hints) 強制規定參數的資料型態,FastAPI 會自動進行驗證與轉換。它能避免因為資料類型錯誤導致的程式崩潰,如果傳入的資料類型不符,API 會自動回傳清晰的錯誤訊息。
# 指定 user_id 必須是整數 (int)
@app.get("/users/{user_id}")
def read_user(user_id: int):
return {"user_id": user_id, "type": str(type(user_id))}
這裡宣告 user_id 為 int,如果用戶訪問 /users/10,程式會收到整數 10;如果訪問 /users/abc,FastAPI 會直接回傳 HTTP 422 錯誤,告訴用戶輸入無效。
3. 預定義值 (Enum)
使用 Enum 類別來限制路徑參數必須是固定的幾個選項之一,這在設計「狀態」或「類別」篩選時非常有用,同時也能讓 API 文件 (Swagger UI) 自動產生下拉選單。
from enum import Enum
class BookCategory(str, Enum):
fiction = "小說"
tech = "科技"
business = "商業"
@app.get("/books/category/{category}")
async def get_books_by_category(category: BookCategory):
if category is BookCategory.fiction:
return {"category": category.value, "books": ["哈利波特", "魔戒"]}
elif category is BookCategory.tech:
return {"category": category.value, "books": ["Python 實戰", "演算法圖解"]}
return {"category": category.value, "books": ["商業思維", "零售心理學"]}
用戶只能在 URL 中輸入 fiction、tech 或 business,如果輸入其他字串,FastAPI 會拒絕請求並提示允許的可選值。
實作範例
以下是一個模擬電商商品查詢的完整範例,這段程式碼展示了如何結合路徑參數、型別驗證以及錯誤處理 (HTTPException)。
from fastapi import FastAPI, HTTPException
app = FastAPI()
# 模擬資料庫數據
fake_items_db = {
1: {"name": "筆記型電腦", "price": 35000},
2: {"name": "無線滑鼠", "price": 1200},
3: {"name": "機械鍵盤", "price": 4500}
}
@app.get("/products/{product_id}")
def get_product_detail(product_id: int):
"""
透過 product_id 取得商品詳細資訊
"""
# 檢查商品是否存在於模擬資料庫中
if product_id not in fake_items_db:
# 如果不存在,拋出 404 錯誤,並附帶錯誤訊息
raise HTTPException(status_code=404, detail="商品不存在")
# 如果存在,回傳商品 ID 與詳細資料
return {"product_id": product_id, "data": fake_items_db[product_id]}
這個範例定義了 /products/{product_id} 路徑,並要求 product_id 必須是整數。當請求進入時,程式會先檢查該 ID 是否存在於 fake_items_db 中。如果找不到,它會主動拋出 404 Not Found 錯誤,這是符合 RESTful 標準的作法。
常見錯誤與解決方法
新手在使用路徑參數時,經常會遇到路徑解析順序或參數定義不一致的問題。以下是三個最常見的錯誤及其修正方式。
1. 路徑順序錯誤
FastAPI 是按照程式碼順序由上而下匹配路徑的,如果你將動態路徑放在固定路徑之前,固定路徑永遠不會被觸發。
# ❌ 錯誤寫法:/students/current 永遠不會被執行
@app.get("/students/{student_id}")
def get_student(student_id: str):
return {"id": student_id}
@app.get("/students/current")
def get_current_student():
return {"message": "當前登入身分為學生"}
# ✅ 正確寫法:將特定路徑放在動態路徑之前
@app.get("/students/current")
def get_current_student():
return {"message": "當前登入身分為學生"}
@app.get("/students/{student_id}")
def get_student(student_id: str):
return {"id": student_id}
2. 函式參數名稱不一致
路徑裝飾器中定義的參數名稱,必須與下方函式接收的參數名稱完全一致。如果不一致,FastAPI 會報錯或無法正確傳遞數值。
# ❌ 錯誤寫法:路徑是 item_id,但函式接收 id
@app.get("/items/{item_id}")
def read_item(id: int): ...
# ✅ 正確寫法:兩者名稱必須完全相同
@app.get("/items/{item_id}")
def read_item(item_id: int): ...
3. 忽略型別宣告導致運算錯誤
如果沒有指定型別,FastAPI 預設將參數視為字串 (string)。如果你直接對其進行數學運算,就會拋出 TypeError。
# ❌ 錯誤寫法:item_id 預設為 str,字串不能加 1
@app.get("/calc/{item_id}")
def calculate(item_id):
return item_id + 1
# ✅ 正確寫法:明確宣告 int,FastAPI 會先轉換型別
@app.get("/calc/{item_id}")
def calculate(item_id: int):
return item_id + 1
結語
學會路徑參數是使用 FastAPI 開發後端的第一步,你需要記住:使用 {} 定義路徑、透過型別提示 (int, str) 進行數據驗證,並特別注意「固定路徑必須排在動態路徑之前」的順序規則。














