FastAPI 是一個用 Python 寫高效能 API 的現代框架,靠型別提示自動產生資料驗證與 Swagger 文件,原生支援 async,效能逼近 Go/Node.js。2026 年 8 月最新版為 0.141(搭配 Pydantic 2.13、Uvicorn 0.52),只要會 Python 基礎,30 分鐘就能寫出第一個生產級 API。
一句話結論
FastAPI 是 2026 年 Python 開發者寫 API 的首選:用型別提示(type hints)同時搞定「參數驗證、資料序列化、自動文件」三件事,內建 async 支援、自動生成 Swagger UI(/docs),部署只需一行 uvicorn main:app。本教學所有程式碼都經過實測,跟著做就能跑。
FastAPI 是什麼?為什麼 2026 年值得學
FastAPI 由 Sebastián Ramírez 於 2018 年發布,底層架構是 Starlette(ASGI 框架)+ Pydantic(資料驗證) 的組合。它的核心設計哲學:你的型別提示就是契約——寫下 item_id: int,FastAPI 自動做型別轉換、驗證失敗回傳 422、並把參數結構畫進文件。
先看它與另外兩大 Python Web 框架的定位差異:
| 面向 | FastAPI | Flask | Django |
|---|---|---|---|
| 定位 | 高效能 API 框架 | 輕量微框架 | 全功能 Web 框架 |
| 非同步 | ✅ 原生 ASGI/async | ⚠️ WSGI,async 需額外套件 | ⚠️ WSGI 為主(ASGI 支援較晚) |
| 資料驗證 | ✅ 內建(Pydantic v2) | ❌ 自己寫 | ⚠️ DRF 才有 |
| API 文件 | ✅ 自動(Swagger/ReDoc) | ❌ 需 flask-swag 等 | ⚠️ DRF 需額外設定 |
| 內建 ORM/Admin | ❌ 無(可選 SQLAlchemy) | ❌ 無 | ✅ 完整 |
| 適合場景 | 前後端分離、AI 服務、微服務 | 小工具、輕量 Web | 大型全端產品、後台系統 |
| 學習曲線 | 中(需懂型別提示) | 低 | 高 |
簡單說:要寫 API 選 FastAPI,要寫完整網站選 Django,要快速起個小服務選 Flask。2026 年的趨勢很明顯——AI 服務(RAG、LLM gateway、Agent 後端)幾乎全部用 FastAPI 當標準骨架,連 MCP Server 生態也大量採用。
安裝:uv 或 pip 二選一
2026 年 Python 套件管理的主流是 uv(超快,由 Rust 寫成)。系統需求:Python 3.10+(FastAPI 0.141 的 requires-python 為 >=3.10,本教學以 Python 3.12 實測)。
# 方法一:uv(推薦,快 10 倍以上)
uv venv .venv && source .venv/bin/activate
uv pip install "fastapi[standard]"
# 方法二:傳統 pip
python -m venv .venv && source .venv/bin/activate
pip install "fastapi[standard]"
[standard] extra 會一併裝好 uvicorn(ASGI 伺服器)、httpx 與其他常用相依。實測版本:fastapi 0.141.1、uvicorn 0.52.4、pydantic 2.13.4。
第一個 API:Hello World
建立 main.py:
from fastapi import FastAPI
app = FastAPI(title="範例 API", version="1.0.0")
@app.get("/")
def root():
return {"message": "Hello most.tw"}
啟動開發伺服器:
uvicorn main:app --reload --port 8000
--reload:開發模式,改程式碼自動重啟main:app:main.py中的app物件
打開 http://localhost:8000 會看到 {"message":"Hello most.tw"}。接著訪問 http://localhost:8000/docs——恭喜,你什麼都沒寫就獲得了一份可互動的 Swagger UI 文件,每個端點都能直接測試。
路徑參數與查詢參數:型別提示就是驗證
FastAPI 最神奇的地方:參數型別寫下去,驗證自動生效。
@app.get("/items/{item_id}")
def read_item(item_id: int): # 路徑參數,自動轉 int
return {"item_id": item_id, "name": f"商品 {item_id}"}
@app.get("/items/")
def list_items(
min_price: float = 0, # 查詢參數 ?min_price=100
limit: int = 10, # 可選,預設 10
keyword: str | None = None, # 可選,可為空
):
return {"min_price": min_price, "limit": limit, "keyword": keyword}
實測行為:
| 請求 | 結果 |
|---|---|
GET /items/3 | {"item_id":3,"name":"商品 3"}(自動轉 int) |
GET /items/abc | 422:型別驗證失敗(自動) |
GET /items/?min_price=100&limit=5 | 查詢參數正常解析 |
GET /items/?limit=abc | 422:驗證失敗 |
不用寫任何 if/else 檢查,型別錯誤全部由框架攔截,這在傳統 Flask 裡要自己寫一堆 try/except int()。
Pydantic v2 資料模型:POST 請求的驗證神器
寫 API 遲早要收 JSON body。FastAPI 的做法是定義一個 Pydantic v2 模型,欄位規則寫在型別裡:
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(min_length=1, max_length=50) # 1~50 字
price: float = Field(gt=0, description="單價,必須大於 0")
stock: int = Field(default=0, ge=0) # 預設 0,不可為負
@app.post("/items", status_code=201)
def create_item(item: Item):
# item 已經是驗證過、型別正確的物件
return {"id": 1, **item.model_dump()}
用 Postman/curl 測試無效資料:
curl -X POST http://localhost:8000/items \
-H "Content-Type: application/json" \
-d '{"name": "", "price": -5}'
回傳 422 與精確的錯誤訊息:
{"detail": [
{"type": "string_too_short", "loc": ["body", "name"], "msg": "String should have at least 1 character"},
{"type": "greater_than", "loc": ["body", "price"], "msg": "Input should be greater than 0"}
]}
每個欄位的錯誤都清楚標明「哪裡錯、為什麼錯」——前端可以直接拿來顯示錯誤訊息,後端不需要寫任何一行驗證邏輯。注意 Pydantic v2 的 API 差異:取資料用 model_dump()(v1 是 .dict()),Field(gt=0) 取代 v1 的 Field(gt=0) 寫法,驗證錯誤訊息也全面重寫。
依賴注入:把共用的邏輯抽出來
當多個端點都需要同一份邏輯(驗證 Token、拿資料庫連線、算 id),FastAPI 的 Depends 讓你把依賴宣告成函式,框架自動注入:
from typing import Annotated
from fastapi import Depends
def get_next_id() -> int: # 依賴函式
global _next_id
return _next_id
@app.post("/items", status_code=201)
def create_item(
item: Item,
next_id: Annotated[int, Depends(get_next_id)], # 注入依賴
):
...
依賴注入的好處:測試時可以覆寫依賴(例如換成假的資料庫),程式碼更乾淨、更好測。Annotated[int, Depends(...)] 是 2026 年的標準寫法(取代舊的 next_id: int = Depends(...) 預設值寫法,後者仍有相容警告)。
async 端點:什麼時候該用
FastAPI 原生支援 async/await:
import asyncio
@app.get("/health")
async def health():
return {"status": "ok"}
@app.get("/slow")
async def slow_task():
await asyncio.sleep(2) # 模擬 IO 等待(查 DB、呼叫外部 API)
return {"done": True}
關鍵觀念:async 只對「等待型工作」有益(網路請求、DB 查詢、檔案 IO)。如果是 CPU 密集運算(影像處理、大迴圈),async 反而會卡住整個 event loop——這種情況要丟給執行緒池(def 端點 FastAPI 自動用執行緒池處理)或背景任務。實務規則:端點內有 await 就宣告 async,沒有就保持一般 def。
測試:用 TestClient 寫 API 測試
FastAPI 內建測試方案(使用 httpx + pytest):
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_create_and_read_item():
r = client.post("/items", json={"name": "機械鍵盤", "price": 2990, "stock": 10})
assert r.status_code == 201
assert r.json()["id"] == 1
r = client.get("/items/1")
assert r.status_code == 200
assert r.json()["name"] == "機械鍵盤"
def test_invalid_item_returns_422():
r = client.post("/items", json={"name": "", "price": -5})
assert r.status_code == 422
pip install pytest
pytest -v
不需要真的啟動伺服器,TestClient 直接在記憶體內模擬 HTTP 請求,CI 裡跑又快又穩。
部署:Docker + uvicorn 多 worker
開發用 --reload,生產環境要關掉 reload 並開多 worker。最標準的做法是 Docker:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
docker build -t my-api .
docker run -p 8000:8000 my-api
graph LR
A[使用者] --> B[Nginx/Cloudflare<br/>反向代理 + TLS]
B --> C[uvicorn worker 1]
B --> D[uvicorn worker 2]
B --> E[uvicorn worker 3]
C --> F[(PostgreSQL/Redis)]
D --> F
E --> F部署注意事項:
- worker 數約等於 CPU 核心數,async 服務可視情況調高
- 前面一定要掛 反向代理(Nginx / Caddy / Cloudflare),負責 TLS 終止與靜態檔
- 環境變數用
pydantic-settings管理,不要把密碼寫進程式碼 - CORS 要設定:
app.add_middleware(CORSMiddleware, allow_origins=[...]),否則前端跨域呼叫會被瀏覽器擋掉
2026 年 FastAPI 生態速覽
| 套件 | 用途 |
|---|---|
| SQLAlchemy 2 + Alembic | 資料庫 ORM 與 migration(async 版本支援) |
| pydantic-settings | 環境變數/設定管理 |
| FastAPI Users / AuthX | 認證與授權 |
| Celery / Arq | 背景任務佇列 |
| LangChain / FastMCP | AI 應用與 MCP Server 整合 |
常見陷阱
- Pydantic v1 舊語法:網路上很多舊教學用
.dict()、Field(..., gt=0)——v2 要用model_dump()、Field(gt=0) - sync 端點做 CPU 密集工作:會卡住 event loop,用 def 宣告讓 FastAPI 丟執行緒池
- 忘了 CORS:前端串接全部被瀏覽器攔截
--reload上生產:開發模式會重載,效能差且不安全- 路徑順序陷阱:
/items/與/items/{item_id}這種「同前綴、一個有斜線」的路由,宣告順序與斜線會影響匹配,實測GET /items/1會正確進路徑參數版本
結語
FastAPI 把 API 開發的「髒活」——驗證、序列化、文件、async——全部用型別提示自動化。2026 年它已經是 Python 生態寫 API 的事實標準,學會它等於拿到 AI 服務、微服務、內部工具後端的通用門票。建議下一步:把這篇範例擴充成連接 SQLite/PostgreSQL 的完整 CRUD,或試著包一個 AI 模型的推論端點。
延伸閱讀
- 期末專題 (二):建構 FastAPI 股市資料服務 (第 46 章)
- 什麼是 Webhook?白話文完整教學:與 API 輪詢的差異、Python FastAPI 實作與安全驗證
- MCP 完整教學 2026:什麼是 Model Context Protocol?從架構、三大原語到 Python 實作第一個 MCP Server 的權威指南
- DuckDB 完整教學 2026:從安裝到查詢 Parquet 實戰,資料分析神器 v2.0 新功能一次看懂
資料來源
- FastAPI 官方文件
- FastAPI PyPI(版本 0.141.1)
- Pydantic v2 官方文件
- Uvicorn 官方文件
- 本文所有程式碼皆於 fastapi 0.141.1 / pydantic 2.13.4 / uvicorn 0.52.4 環境實測通過
