Python FastAPI 後端 API 開發入門:從零到部署的完整教學
三年前我開始用 FastAPI 做後端,現在回頭看,這是我 Python 職涯中最好的技術決定之一。FastAPI 的設計哲學——快速、簡潔、有型別安全——跟現代 API 開發的需求完美契合。如果你還在用 Flask 或 Django REST Framework,真的可以考慮轉一下。
為什麼 2026 年要選 FastAPI
Python Web 框架有很多選擇,為什麼 FastAPI 會在 2026 年成為最熱門的選項?幾個關鍵理由:
效能卓越:FastAPI 基於 ASGI(Async Server Gateway Interface),原生支援非同步處理。在高並發場景下,效能是 Flask 的 5-10 倍。底層使用 Starlette 和 Uvicorn,可以跟 Node.js 相提並論。
自動產生文件:寫好 API 就自動有 Swagger UI 和 ReDoc 文件,不用額外維護。這對前後端協作太重要了。
型別安全:搭配 Pydantic v2 做資料驗證,在執行期就能抓到資料格式問題。寫過 TypeScript 的人會覺得很親切。
AI 生態系整合:FastAPI 是 AI/ML 應用最常用的 API 框架。幾乎所有的 LLM 服務、WebSocket 即時應用都用 FastAPI 做後端。
跟其他框架的定位區別:Flask 適合小型專案和快速原型、Django 適合大型的全端應用、FastAPI 適合中大型的 API 服務和微服務。
環境建置:用 uv 快速開始
2026 年建 Python 專案建議用 uv,比 pip 和 poetry 快超多:
# 安裝 uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# 建立專案
uv init my-api
cd my-api
# 安裝依賴
uv add fastapi uvicorn[standard] pydantic
# 開發用依賴
uv add --dev pytest httpx
建立專案結構:
my-api/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app 入口
│ ├── models.py # Pydantic models
│ ├── routers/ # API 路由
│ │ ├── __init__.py
│ │ └── items.py
│ └── database.py # 資料庫設定
├── tests/
│ └── test_items.py
├── pyproject.toml
└── Dockerfile
第一支 API:五分鐘寫出 CRUD
先來做一個最基本的 CRUD API:
# app/main.py
from fastapi import FastAPI
app = FastAPI(
title="My API",
description="學習用的 API",
version="1.0.0"
)
# 暫時用 dict 當資料庫
items_db: dict[int, dict] = {}
counter = 0
@app.post("/items/", status_code=201)
async def create_item(name: str, price: float):
global counter
counter += 1
item = {"id": counter, "name": name, "price": price}
items_db[counter] = item
return item
@app.get("/items/")
async def list_items():
return list(items_db.values())
@app.get("/items/{item_id}")
async def get_item(item_id: int):
if item_id not in items_db:
from fastapi import HTTPException
raise HTTPException(status_code=404, detail="Item not found")
return items_db[item_id]
@app.put("/items/{item_id}")
async def update_item(item_id: int, name: str, price: float):
if item_id not in items_db:
from fastapi import HTTPException
raise HTTPException(status_code=404, detail="Item not found")
items_db[item_id] = {"id": item_id, "name": name, "price": price}
return items_db[item_id]
@app.delete("/items/{item_id}", status_code=204)
async def delete_item(item_id: int):
if item_id not in items_db:
from fastapi import HTTPException
raise HTTPException(status_code=404, detail="Item not found")
del items_db[item_id]
啟動:
uvicorn app.main:app --reload
打開 http://localhost:8000/docs 就能看到自動產生的 Swagger 文件,直接在上面測試 API。
Pydantic 資料驗證:API 的品質保證
上面的範例把參數直接放在函式簽名裡,實務上我們會用 Pydantic Model 來定義更嚴格的資料結構:
# app/models.py
from pydantic import BaseModel, Field
class ItemCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=100,
description="商品名稱")
price: float = Field(..., gt=0, description="商品價格,必須大於 0")
description: str | None = Field(None, max_length=500)
tags: list[str] = Field(default_factory=list)
class ItemResponse(ItemCreate):
id: int
class ItemUpdate(BaseModel):
name: str | None = Field(None, min_length=1, max_length=100)
price: float | None = Field(None, gt=0)
description: str | None = None
tags: list[str] | None = None
然後在路由中使用這些 Model:
# app/routers/items.py
from fastapi import APIRouter, HTTPException
from app.models import ItemCreate, ItemResponse, ItemUpdate
router = APIRouter(prefix="/items", tags=["items"])
@router.post("/", response_model=ItemResponse, status_code=201)
async def create_item(item: ItemCreate):
# Pydantic 自動驗證所有欄位
# 如果 price <= 0 或 name 為空,會自動回傳 422 錯誤
...
@router.patch("/{item_id}", response_model=ItemResponse)
async def update_item(item_id: int, item: ItemUpdate):
# ItemUpdate 所有欄位都是 Optional
# 只更新有傳入的欄位
...
Pydantic v2 的效能比 v1 快了 5-50 倍,所以不用擔心驗證會成為瓶頸。
資料庫整合:SQLAlchemy + async
實務專案一定需要資料庫。FastAPI 搭配 SQLAlchemy 2.0 的 async 模式是最主流的組合:
# app/database.py
from sqlalchemy.ext.asyncio import (
create_async_engine, AsyncSession, async_sessionmaker
)
from sqlalchemy.orm import DeclarativeBase
DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/mydb"
engine = create_async_engine(DATABASE_URL)
async_session = async_sessionmaker(engine, class_=AsyncSession)
class Base(DeclarativeBase):
pass
async def get_db():
async with async_session() as session:
yield session
定義 ORM Model:
from sqlalchemy import String, Float
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class Item(Base):
__tablename__ = "items"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
price: Mapped[float] = mapped_column(Float)
description: Mapped[str | None] = mapped_column(String(500), nullable=True)
在路由中使用 Dependency Injection 注入資料庫 session,這是 FastAPI 最優雅的設計之一。
認證與授權:JWT 實作
API 安全是不能跳過的。FastAPI 內建了 OAuth2 和 JWT 的支援:
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer
import jwt
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
user_id = payload.get("sub")
if user_id is None:
raise HTTPException(status_code=401)
return user_id
except jwt.InvalidTokenError:
raise HTTPException(status_code=401)
# 使用認證保護路由
@router.get("/me")
async def read_users_me(user_id: str = Depends(get_current_user)):
return {"user_id": user_id}
Depends() 是 FastAPI 的依賴注入系統,非常靈活。你可以用它做認證、資料庫連線、快取、限流等各種中間件功能。
測試策略:確保 API 品質
FastAPI 的測試非常方便,用 httpx 的 AsyncClient 搭配 pytest:
import pytest
from httpx import AsyncClient, ASGITransport
from app.main import app
@pytest.mark.anyio
async def test_create_item():
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.post("/items/", json={
"name": "Test Item",
"price": 9.99
})
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Item"
assert data["price"] == 9.99
@pytest.mark.anyio
async def test_create_item_invalid_price():
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.post("/items/", json={
"name": "Bad Item",
"price": -5 # 應該被 Pydantic 擋下
})
assert response.status_code == 422
建議測試覆蓋率至少要有正常路徑 + 常見錯誤路徑。不需要追求 100% 覆蓋率,但核心業務邏輯一定要測到。
部署上線:Docker + Cloud Run
最後來談部署。2026 年最常見的部署方式是 Docker + 雲端容器服務:
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
# 安裝 uv 並安裝依賴
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
COPY app/ app/
CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
部署到 Google Cloud Run:
# 建構並推送 Docker Image
gcloud builds submit --tag gcr.io/PROJECT_ID/my-api
# 部署到 Cloud Run
gcloud run deploy my-api --image gcr.io/PROJECT_ID/my-api --platform managed --region asia-east1 --allow-unauthenticated
當然你也可以用 Railway、Fly.io、Render 這些更簡單的平台。如果要自架,可以搭配 CLI 工具做自動化部署腳本。
FastAPI 的學習曲線不陡,但要做好一個生產級的 API 還有很多細節要注意:錯誤處理、日誌系統、監控、資料分析等。建議先把基礎打穩,再逐步加入進階功能。一步一步來,不要急。
繼續閱讀
Python Pydantic V2 資料驗證完整教學:從 BaseModel 到自訂驗證器實戰指南
相關文章
你可能也喜歡
探索其他領域的精選好文