FastAPI狀態碼詳解:200、404、500等使用場景

什麼是HTTP狀態碼?

HTTP狀態碼是服務器向客戶端返回的數字代碼,用於表示請求的處理結果。比如“200”表示請求成功,“404”表示請求的資源不存在。在FastAPI中,正確設置狀態碼能幫助API客戶端(如前端、其他服務)準確理解請求結果,是構建健壯API的基礎。

FastAPI中如何設置狀態碼?

FastAPI提供了兩種常用方式設置狀態碼:
1. 直接在路由函數返回時指定:通過元組 (數據, 狀態碼) 返回。
2. 使用HTTPException異常:拋出帶有狀態碼和錯誤信息的異常(推薦用於錯誤場景)。

示例代碼(兩種方式對比):

from fastapi import FastAPI, HTTPException

app = FastAPI()

# 方式1:直接返回元組
@app.get("/hello")
def say_hello():
    return {"message": "Hello"}, 200  # 返回200 OK

# 方式2:拋出HTTPException(錯誤場景)
@app.get("/users/{user_id}")
def get_user(user_id: int):
    if user_id != 1:
        raise HTTPException(
            status_code=404,
            detail="User not found"
        )
    return {"user_id": user_id, "name": "Alice"}

常見狀態碼及使用場景

以下是初學者最常用的狀態碼,附簡單示例幫助理解:

1. 200 OK:請求成功

場景:GET/POST/PUT等請求處理成功時返回,返回具體數據或結果。
示例:查詢存在的用戶信息:

fake_users_db = {1: {"name": "Alice"}, 2: {"name": "Bob"}}

@app.get("/users/{user_id}")
def get_user(user_id: int):
    if user_id in fake_users_db:
        return fake_users_db[user_id]  # 自動返回200 OK
    raise HTTPException(status_code=404, detail="User not found")  # 不存在返回404
2. 404 Not Found:資源不存在

場景:請求的資源(如ID、路徑)不存在時返回,常見於GET/DELETE請求找不到目標。
示例:請求不存在的用戶ID:

@app.get("/users/{user_id}")
def get_user(user_id: int):
    if user_id not in fake_users_db:
        return {"error": "User not found"}, 404  # 返回404
    return fake_users_db[user_id]
3. 500 Internal Server Error:服務器內部錯誤

場景:服務器代碼出錯、數據庫連接失敗等服務器端問題時返回(儘量避免暴露給用戶,應捕獲異常返回友好提示)。
錯誤示例(避免):

@app.get("/crash")
def crash():
    1 / 0  # 故意製造錯誤,FastAPI默認返回500(但實際應捕獲!)

正確處理:用try-except捕獲並返回400等具體錯誤:

from fastapi import HTTPException

@app.get("/divide")
def divide(a: float, b: float):
    try:
        return a / b
    except ZeroDivisionError:
        raise HTTPException(status_code=400, detail="除數不能爲0")
4. 201 Created:資源創建成功

場景:POST請求創建新資源(如新增用戶、商品)成功時返回,需返回新資源的信息。
示例:創建新用戶:

@app.post("/users")
def create_user(new_user: dict):  # 假設接收新用戶數據
    new_id = 3  # 數據庫新增ID
    created_user = {"id": new_id, **new_user}
    return created_user, 201  # 返回201和創建的用戶
5. 204 No Content:無內容返回

場景:DELETE/PUT請求成功但無需返回數據(如刪除資源後),僅返回狀態碼。
示例:刪除用戶:

from fastapi import status

@app.delete("/users/{user_id}")
def delete_user(user_id: int):
    if user_id in fake_users_db:
        del fake_users_db[user_id]
        return {"message": "User deleted"}, status.HTTP_204_NO_CONTENT  # 204無內容
    raise HTTPException(status_code=404, detail="User not found")
6. 400 Bad Request:請求參數錯誤

場景:請求參數不合法(如必填字段缺失、格式錯誤)時返回。
示例:提交負數價格(Pydantic模型驗證):

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float

@app.post("/items")
def create_item(item: Item):
    if item.price < 0:
        raise HTTPException(status_code=400, detail="價格不能爲負數")
    return item, 201
7. 401 Unauthorized / 403 Forbidden
  • 401:未認證(用戶未登錄)。
    示例:訪問需登錄的接口:
  from fastapi import Depends, HTTPException
  from fastapi.security import OAuth2PasswordBearer

  oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

  async def get_current_user(token: str = Depends(oauth2_scheme)):
      if not token:  # 假設token不存在則未認證
          raise HTTPException(status_code=401, detail="未認證")

  @app.get("/profile")
  def get_profile(user=Depends(get_current_user)):
      return {"message": "已登錄"}
  • 403:已認證但權限不足(如普通用戶訪問管理員接口)。
    示例:普通用戶訪問管理員接口:
  async def get_admin_role(user: dict = Depends(get_current_user)):
      if user.get("role") != "admin":
          raise HTTPException(status_code=403, detail="權限不足")

  @app.get("/admin")
  def admin_route(user=Depends(get_admin_role)):
      return {"message": "管理員數據"}

最佳實踐:不同HTTP方法的狀態碼習慣

  • GET:查詢數據,成功返回200,失敗返回404(資源不存在)或400(參數錯誤)。
  • POST:創建資源,成功返回201,參數錯誤返回400。
  • PUT/PATCH:更新資源,成功返回200或204,失敗返回400/404。
  • DELETE:刪除資源,成功返回204,失敗返回404。

總結

狀態碼是API的“語言”,正確使用能讓客戶端清晰理解請求結果。FastAPI通過status_code參數和HTTPException簡化了狀態碼設置,初學者需重點掌握200(成功)、404(資源不存在)、500(服務器錯誤)、201(創建成功)、400(參數錯誤)等核心狀態碼的場景,避免因狀態碼混亂導致前端或下游服務錯誤。

(注:FastAPI自動生成的Swagger文檔會顯示路由的狀態碼,調試時可通過文檔直觀查看各接口的狀態碼定義。)

小夜