回應與自動文件
輸入驗證只完成一半合約。你還要決定回給客戶端什麼,以及文件是否與實際輸出一致。response_model 負責過濾輸出;/docs 則是這份合約的即時畫面。
用 response_model 過濾輸出
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
class UserOut(BaseModel):
username: str
@app.post("/users/", response_model=UserOut)
def create_user(user: UserIn):
return user
函式雖然拿到含密碼的 UserIn,回傳時只會留下 UserOut 宣告的欄位。密碼不會出現在 JSON 裡,文件也只顯示公開欄位。這是避免「多回傳內部欄位」最便宜的方法。
也可以寫回傳型別提示 -> UserOut,效果相近;需要同時指定狀態碼或好幾種回應時,再用 response_model 與 responses 參數。
狀態碼與沒有內容的回應
預設成功是 200。建立資源時常用 201:
from fastapi import status
@app.post("/items/", response_model=ItemPublic, status_code=status.HTTP_201_CREATED)
def create_item(item: ItemCreate):
return saved_item
刪除成功且沒有 body,可用 Response 配 204。重點是:狀態碼要表達結果,不要全部回 200 再在 JSON 裡寫 "ok": false。
/docs、/redoc 與 OpenAPI
FastAPI 依你的路徑、參數、模型產生 OpenAPI schema,再交給:
- Swagger UI(
/docs):適合開發時試打、看請求範例。 - ReDoc(
/redoc):適合閱讀整體 API。 /openapi.json:給程式用,可產生 TypeScript / Kotlin 等客戶端。
文件好不好看,取決於你有沒有寫:
- 路徑操作函式的 docstring
Path/Query/Field的descriptionresponse_model(否則文件只能猜你回了什麼)tags=["商品"]把端點分組
@app.get("/items/{item_id}", response_model=ItemPublic, tags=["商品"])
def read_item(item_id: int):
"""依編號取得單一商品。找不到時回 404。"""
...
應用標題與版本可在建立實例時設定:FastAPI(title="商店 API", version="1.0.0")。