這篇文章將教你如何使用 FastAPI 框架,快速建立一個具備新增、讀取、更新、刪除功能的待辦事項 API。
什麼是 CRUD?
CRUD 代表 Create(新增)、Read(讀取)、Update(更新)與 Delete(刪除),是操作資料最基本的四個動作,對應到 HTTP 方法分別是 POST、GET、PUT、DELETE。
CRUD 實作範例
以下是一個完整的單一檔案範例,實作待辦事項的 CRUD 功能。資料暫時儲存在一個 Python List 變數中,伺服器重啟後資料會重置。from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
# ----------------------
# 1. Pydantic 模型定義
# ----------------------
# 基礎模型:新增時使用 (title 為必填)
class TodoCreate(BaseModel):
title: str
description: str | None = None
is_completed: bool = False
# 回傳模型:繼承基礎模型,但多加了 ID (由後端產生)
class TodoResponse(TodoCreate):
id: int
# ----------------------
# 2. 模擬資料庫
# ----------------------
fake_db: list[TodoResponse] = []
current_id_counter = 0
# ----------------------
# 3. API 路由實作
# ----------------------
# 1. Create (新增)
@app.post("/todos/", response_model=TodoResponse)
def create_todo(todo_in: TodoCreate):
global current_id_counter
current_id_counter += 1
new_todo = TodoResponse(id=current_id_counter, **todo_in.model_dump())
fake_db.append(new_todo)
return new_todo
# 2. Read (讀取所有)
@app.get("/todos/", response_model=list[TodoResponse])
def read_todos():
return fake_db
# 3. Read (讀取單一)
@app.get("/todos/{todo_id}", response_model=TodoResponse)
def read_todo(todo_id: int):
for item in fake_db:
if item.id == todo_id:
return item
raise HTTPException(status_code=404, detail="待辦事項不存在")
# 4. Update (更新):使用 PUT (整筆替換)
@app.put("/todos/{todo_id}", response_model=TodoResponse)
def update_todo(todo_id: int, todo_in: TodoCreate):
for index, item in enumerate(fake_db):
if item.id == todo_id:
updated_item = TodoResponse(id=todo_id, **todo_in.model_dump())
fake_db[index] = updated_item
return updated_item
raise HTTPException(status_code=404, detail="待辦事項不存在")
# 5. Delete (刪除)
@app.delete("/todos/{todo_id}")
def delete_todo(todo_id: int):
for index, item in enumerate(fake_db):
if item.id == todo_id:
del fake_db[index]
return {"message": "刪除成功"}
raise HTTPException(status_code=404, detail="待辦事項不存在")
這段程式碼建立了一個 API 服務,透過 fake_db 列表來模擬資料庫行為。create_todo 負責將資料加入列表,read_todos 回傳整個列表。update_todo 和 delete_todo 則透過迴圈尋找對應 ID 的項目進行修改或移除,若找不到 ID 則回傳 404 錯誤。
常見錯誤與解決方法
1. HTTP 方法使用錯誤
誤用 GET 來傳送敏感或新增的資料,或者用 POST 來獲取資料。這不僅不符合 RESTful 規範,也可能導致預期外的行為。
# 錯誤寫法:試圖用 GET 來新增資料 (不符合規範且不安全)
@app.get("/create_todo/")
def create_wrong(item: TodoCreate):
fake_db.append(item)
# 正確寫法:新增資料應該使用 POST
@app.post("/todos/")
def create_right(item: TodoCreate):
fake_db.append(item)
2. 未處理資料不存在的情況
在更新或刪除時,直接操作資料而未檢查 ID 是否存在,這不會導致程式崩潰(如果邏輯寫得好),但會給前端錯誤的回應狀態(例如回傳 200 OK 但什麼都沒做)。
# 錯誤寫法:找不到 ID 時回傳 None 或空值,讓前端困惑
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
for i, item in enumerate(fake_db):
if item.id == item_id:
del fake_db[i]
# 這裡如果不寫 return,預設回傳 null,狀態碼 200
# 正確寫法:找不到時明確拋出 404
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
for i, item in enumerate(fake_db):
if item.id == item_id:
del fake_db[i]
return {"msg": "Deleted"}
raise HTTPException(status_code=404, detail="Item not found")
結語
CRUD 的重點在於正確對應 HTTP 方法、利用 Pydantic 進行嚴格的資料驗證,以及妥善處理資料不存在時的異常狀況。掌握這些基礎邏輯後,你已經準備好正式連接資料庫了。












