前言
--
Java 開發者也能看懂的 Python 高效能框架指南
最近這幾年,Python 在 AI 和資料處理領域如日中天,很多 Java 開發者也開始接觸 Python 生態系。
在 Python 的眾多 Web 框架中,FastAPI 的崛起速度令人瞠目結舌。
在 GitHub 上,FastAPI 已經斬獲了 80K+ Star,成長速度超過 Flask 和 Django,成為 Python 生態中成長最快的 Web 框架。
微軟、Netflix、滴滴等公司都在正式環境中使用它。
很多朋友問我:「三哥,我一個寫 Java 的,為什麼要學 FastAPI?」
我的回答很簡單:如果你需要快速搭建一個高效能的 API 服務,尤其是涉及 AI 模型部署、資料處理或微服務場景,FastAPI 可能是目前最好的選擇之一。
今天這篇文章,我就從 Java 開發者的視角出發,用你熟悉的對比方式,把 FastAPI 從頭到尾講清楚。
圖文並茂,程式碼可複製,跟著做就行。
希望對你有所幫助。
更多專案實戰在我的技術網站:susan.net.cn/project
FastAPI 是一個基於 Python 的現代 Web 框架,專為 建構高效能 API 而設計。
它由西班牙開發者 Sebastián Ramírez 於 2018 年建立,核心設計目標是解決傳統 Python Web 框架在效能、開發效率和型別安全方面的痛點。
它的技術定位可以概括為「三高」:高開發效率、高執行效能、高型別安全。
為了讓 Java 開發者快速理解 FastAPI 的定位,我用一個表格來對比:
| 對比維度 | FastAPI(Python) | Spring Boot(Java) | Flask(Python) |
|---|---|---|---|
| 核心定位 | 高效能 API 框架 | 企業級全端框架 | 輕量級微框架 |
| 效能 | 極高(接近 Go/Node.js) | 高 | 中等 |
| 開發速度 | 極快 | 較慢 | 快 |
| 自動文件 | ✅ 原生支援 | 需 SpringDoc 等整合 | ❌ 需第三方 |
| 型別安全 | ✅ Pydantic 強驗證 | ✅ Java 強型別 | ⚠️ 較弱 |
| 非同步支援 | ✅ 原生 async/await | ✅ Spring WebFlux | ⚠️ 需擴充 |
| 學習曲線 | 低 | 陡峭 | 低 |
| 適用場景 | API 服務、微服務、AI 部署 | 大型企業應用 | 簡單 Web 應用 |
FastAPI 和 Spring Boot 的關係,有點像 跑車和 SUV——跑車輕快靈活,適合高速衝刺;SUV 穩重紮實,適合長途跋涉和複雜路況。
各有各的好,關鍵看你要做什麼。
FastAPI 官方文件總結了它的核心能力:
高效能:基於 Starlette(非同步 Web 框架)和 Pydantic(高效能資料驗證),在 Python Web 框架中屬於效能天花板。
自動生成 API 文件:無需編寫文件,自動生成 Swagger UI(/docs)和 ReDoc(/redoc)。
使用 Python 型別提示自動驗證參數:自動請求參數驗證、自動回應模型驗證、IDE 自動補全體驗極佳。
原生非同步支援:完全支援 async/await,適合高併發 I/O 場景。
依賴注入系統:支援權限驗證、Token 驗證、DB 會話管理、統一行為注入。
易維護:型別提示 + 自動補全,適合微服務架構。
有些朋友可能會問:同樣是 Python 寫的,FastAPI 憑什麼比 Flask 快那麼多?
答案是三個字:ASGI。
傳統的 Python Web 框架(如 Flask、Django)基於 WSGI(Web Server Gateway Interface)規範。
WSGI 是 同步 的——每個請求獨占一個執行緒,直到處理完才能釋放。這就好比一間餐廳裡,每個服務生一次只能服務一桌客人,其他客人只能乾等著。
而 FastAPI 基於 ASGI(Asynchronous Server Gateway Interface)規範。
ASGI 是 非同步非阻塞 的——每個請求在事件迴圈中被排程,而不是獨占執行緒資源。
這就像同一個服務生可以同時服務多桌客人——點完一桌的菜,趁廚房做菜的時間去幫另一桌點單,效率自然高出一大截。
這就是為什麼 FastAPI 能夠輕鬆處理 數千個併發連線。
FastAPI 的架構可以概括為「星型模型」,由三個核心引擎驅動:
① 路由系統:基於路徑操作裝飾器(@app.get、@app.post)實現 RESTful 路由,支援路徑參數和查詢參數的自動解析。其路徑匹配演算法採用正則表示式最佳化,在路徑參數較多時比 Flask 的 Werkzeug 路由 效能提升達 40%。
② 依賴注入系統:透過 Depends 關鍵字實現服務依賴的自動解析,特別適合資料庫連線等資源的統一管理。其底層實現採用函式裝飾器模式,透過 __wrapped__ 屬性保留原始函式,在執行時動態注入依賴項。
③ 資料驗證引擎:FastAPI 的資料驗證基於 Pydantic 的 BaseModel,驗證流程包含欄位型別檢查、約束條件驗證、巢狀模型驗證和額外屬性檢查。
當一個請求到達 FastAPI 時,資料驗證的流程是這樣的:
如果在請求中傳入非字串型別的 username,框架會立即回傳 422 錯誤,並明確指出哪個欄位失敗及原因。
這種「在門口就把不合格的請求攔住」的設計,大大減少了業務程式碼裡的防禦性判斷。
在 TechEmpower 基準測試中,FastAPI 在 JSON 序列化場景下達到 18,732 req/sec(同步模式)和 32,451 req/sec(非同步模式)。
JSON 序列化效能達到 Django 的 8 倍,接近 Go 語言框架 Gin 的水準。
對於 API 開發來說,FastAPI 的速度大約是 Flask 的 2-3 倍。
在 I/O 密集型場景下,這個差距會更加明顯。
建議使用 Python 3.9+ 版本:
bash 代碼解讀複製代碼# 使用 pyenv 管理 Python 版本(推薦)
brew install pyenv
pyenv install 3.11.5
pyenv global 3.11.5
# 或直接使用系統 Python
python3 --version
bash 代碼解讀複製代碼# 建立專案目錄
mkdir fastapi-demo
cd fastapi-demo
# 建立虛擬環境(推薦)
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 安裝 FastAPI 和 Uvicorn
pip install fastapi uvicorn[standard]
Uvicorn 是一個 ASGI 伺服器,相當於 Java 中的 Tomcat 或 Netty。
建立 main.py 檔案:
python 代碼解讀複製代碼from fastapi import FastAPI
# 建立應用程式實例
app = FastAPI(title="我的第一個 FastAPI 應用程式", version="1.0.0")
# 定義路由
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/hello/{name}")
async def say_hello(name: str):
return {"message": f"Hello, {name}!"}
bash 代碼解讀複製代碼uvicorn main:app --reload --host 0.0.0.0 --port 8000
參數說明:
main:app —— main.py 檔案中的 app 實例--reload —— 開發模式下自動重啟(正式環境不要用)--host —— 監聽位址--port —— 埠號啟動後,訪問以下地址:
訪問 /docs 你會看到一份互動式的 API 文件——你什麼都沒寫,文件已經自動生成了。這就是 FastAPI 最讓人驚艷的特性之一。
python 代碼解讀複製代碼from fastapi import FastAPI
app = FastAPI()
# 路徑參數:從 URL 路徑中擷取
@app.get("/users/{user_id}")
async def get_user(user_id: int): # 自動型別轉換 + 驗證
return {"user_id": user_id, "name": f"User_{user_id}"}
# 查詢參數:從 URL 問號後面擷取
@app.get("/items")
async def list_items(
skip: int = 0, # 預設值
limit: int = 10, # 預設值
category: str | None = None # 可選參數
):
return {"skip": skip, "limit": limit, "category": category}
程式碼解讀:
{user_id} 會從 URL 中擷取,user_id: int 會自動進行型別轉換和驗證——傳入非數字會回傳 422 錯誤?skip=0&limit=10 中擷取,有預設值的參數是可選的訪問範例:
GET /users/123 → {"user_id": 123, "name": "User_123"}GET /items?skip=5&limit=20&category=books這是 FastAPI 最核心的能力之一——用 Pydantic 模型定義請求和回應的資料結構。
python 代碼解讀複製代碼from fastapi import FastAPI
from pydantic import BaseModel, Field, EmailStr
from typing import Optional
from datetime import datetime
app = FastAPI()
# 定義請求主體模型
class UserCreate(BaseModel):
username: str = Field(..., min_length=3, max_length=20, description="使用者名稱")
email: EmailStr = Field(..., description="電子郵件地址")
password: str = Field(..., min_length=8, description="密碼")
age: Optional[int] = Field(None, ge=0, le=150, description="年齡")
tags: list[str] = []
# 定義回應體模型
class UserResponse(BaseModel):
id: int
username: str
email: str
age: Optional[int]
created_at: datetime
@app.post("/users", response_model=UserResponse)
async def create_user(user: UserCreate):
# 業務邏輯:建立使用者
return UserResponse(
id=1,
username=user.username,
email=user.email,
age=user.age,
created_at=datetime.now()
)
程式碼解讀:
UserCreate 定義了請求主體的結構,Field 提供了額外的驗證規則(最小長度、最大長度、取值範圍等)EmailStr 會自動驗證電子郵件格式response_model=UserResponse 指定了回應的資料結構,框架會自動過濾掉不在模型中的欄位這就是「宣告式程式設計」的魅力——你只需要宣告「我要什麼」,框架幫你處理「怎麼驗證」。
FastAPI 的依賴注入系統非常靈活,適合處理權限驗證、資料庫會話管理等橫切關注點。
python 代碼解讀複製代碼from fastapi import FastAPI, Depends, Header, HTTPException
app = FastAPI()
# 定義一個依賴:驗證 Token
async def verify_token(authorization: str = Header(...)):
"""從請求標頭中擷取並驗證 Token"""
if not authorization.startswith("Bearer "):
raise HTTPException(status_code=401, detail="無效的驗證格式")
token = authorization.replace("Bearer ", "")
if token != "valid-token":
raise HTTPException(status_code=401, detail="無效的 Token")
return {"user_id": 1, "username": "admin"}
# 使用依賴
@app.get("/protected")
async def protected_route(user: dict = Depends(verify_token)):
return {"message": f"歡迎, {user['username']}!", "user": user}
程式碼解讀:
verify_token 是一個依賴函式,從請求標頭中擷取 Authorization 並驗證Depends(verify_token) 將依賴注入到路由函式中user 參數傳入路由函式這種設計讓 認證邏輯和業務邏輯完全分離,程式碼更清晰、更可測試。
FastAPI 原生支援 async/await,這是它高效能的關鍵。
python 代碼解讀複製代碼import asyncio
from fastapi import FastAPI
app = FastAPI()
# 同步函式(適用於 CPU 密集型操作)
@app.get("/sync")
def sync_endpoint():
# 同步操作,會阻塞執行緒
return {"result": "done"}
# 非同步函式(適用於 I/O 密集型操作)
@app.get("/async")
async def async_endpoint():
# 模擬 I/O 操作:資料庫查詢、外部 API 呼叫等
await asyncio.sleep(1)
# 在等待期間,事件迴圈可以處理其他請求
return {"result": "done after 1 second"}
# 混合使用:在非同步函式中呼叫同步程式碼
@app.get("/mixed")
async def mixed_endpoint():
# 使用 run_in_executor 將同步程式碼放到執行緒池執行
result = await asyncio.to_thread(sync_heavy_work)
return {"result": result}
def sync_heavy_work():
# CPU 密集型操作
return sum(range(1000000))
程式碼解讀:
async def 定義,在等待 I/O 時釋放執行緒資源await asyncio.sleep(1) 模擬 I/O 等待,期間事件迴圈可以處理其他請求asyncio.to_thread 放到執行緒池執行,避免阻塞事件迴圈python 代碼解讀複製代碼from fastapi import FastAPI, Depends
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import declarative_base, Mapped, mapped_column
from sqlalchemy import select
# 資料庫設定
DATABASE_URL = "postgresql+asyncpg://user:password@localhost/db"
engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
Base = declarative_base()
# 定義模型
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
username: Mapped[str] = mapped_column(unique=True)
email: Mapped[str]
# 依賴:取得資料庫會話
async def get_db():
async with AsyncSessionLocal() as session:
yield session
app = FastAPI()
@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User))
users = result.scalars().all()
return [{"id": u.id, "username": u.username, "email": u.email} for u in users]
程式碼解讀:
create_async_engine 建立非同步資料庫引擎AsyncSessionLocal 是非同步會話工廠get_db 是一個依賴,每個請求建立一個資料庫會話,請求結束後自動關閉在正式環境中,統一的回應格式和例外處理是必不可少的。
python 代碼解讀複製代碼from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Generic, TypeVar, Optional
T = TypeVar("T")
class ApiResponse(BaseModel, Generic[T]):
"""統一 API 回應格式"""
code: int = 200
msg: str = "success"
data: Optional[T] = None
app = FastAPI()
@app.get("/users/{user_id}", response_model=ApiResponse)
async def get_user(user_id: int):
if user_id <= 0:
return ApiResponse(code=400, msg="使用者 ID 必須大於 0")
# 模擬查詢
user = {"id": user_id, "name": f"User_{user_id}"}
return ApiResponse(data=user)
python 代碼解讀複製代碼from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(
status_code=exc.status_code,
content={"code": exc.status_code, "msg": exc.detail, "data": None}
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
return JSONResponse(
status_code=500,
content={"code": 500, "msg": "伺服器內部錯誤", "data": None}
)
有了全域例外處理,任何未捕獲的例外都會被統一格式化為規範的回應結構,前端對接時再也不用猜「這個 API 回傳的格式是什麼」了。
中介軟體可以在請求進入路由之前或回應返回之前進行統一處理。
python 代碼解讀複製代碼from fastapi import FastAPI, Request
import time
app = FastAPI()
# 日誌中介軟體:記錄每個請求的耗時
@app.middleware("http")
async def log_requests(request: Request, call_next):
start_time = time.time()
# 記錄請求資訊
print(f"收到請求: {request.method} {request.url.path}")
# 繼續處理請求
response = await call_next(request)
# 記錄回應資訊
process_time = time.time() - start_time
print(f"請求完成: {process_time:.4f} 秒")
# 在回應標頭中加入處理時間
response.headers["X-Process-Time"] = str(process_time)
return response
FastAPI 最讓人驚艷的特性之一,就是 自動生成 API 文件。
你不需要寫任何額外的文件程式碼,FastAPI 會根據你的路由定義、Pydantic 模型和型別註解,自動生成兩份文件:
/docs):互動式文件,可以線上除錯 API/redoc):更美觀的靜態文件python 代碼解讀複製代碼from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI(
title="電商 API",
description="這是一個電商平台的 API 文件",
version="1.0.0",
contact={"name": "技術團隊", "email": "[email protected]"}
)
class Product(BaseModel):
name: str
price: float
stock: int
@app.post("/products",
summary="建立商品",
description="建立一個新的商品,需要提供名稱、價格和庫存",
response_description="建立成功的商品資訊")
async def create_product(product: Product):
"""建立商品介面"""
return {"id": 1, **product.model_dump()}
啟動服務後訪問 /docs,你會看到一份完整的、可互動的 API 文件——參數說明、請求範例、回應範例全部自動生成。
前後端串接時,後端把服務地址發給前端,前端打開 /docs 就能看到所有介面的詳細資訊,還能線上測試。
這種體驗,用過一次就再也回不去了。
1. 極高的開發效率:透過 Python 型別註解自動生成 API 文件,無需手動編寫 Swagger 設定。定義一個使用者註冊介面,程式碼量較傳統框架縮短 60%。在真實專案中,開發週期可以從 6 週縮短至 2 週。
2. 卓越的效能:基於 ASGI 非同步架構,在 TechEmpower 基準測試中 JSON 序列化效能達到 Django 的 8 倍,接近 Go 語言框架 Gin 的水準。
3. 自動文件生成:寫程式碼的同時文件自動生成,前後端串接效率大幅提升。
4. 型別安全:透過 Pydantic 模型在執行時自動檢查資料型別,錯誤回應會準確指出哪個欄位失敗及原因。
5. 原生非同步支援:天生支援 async/await,非常適合 I/O 密集型工作負載(API 呼叫、資料庫查詢、檔案操作)。
6. 依賴注入系統:非常靈活,支援權限驗證、Token 驗證、DB 會話管理等。
7. 生產級特性:內建 CORS、GZip、HTTPS 重新導向等中介軟體,支援 WebSocket 即時通訊。
1. 生態不如 Django 完善:ORM、Admin 等功能不如 Django 完整。
2. Pydantic 學習成本:初學者需要適應 Model 模式。
3. 高度依賴型別提示:程式碼量相比 Flask 會多一些。
4. 部分元件需自行封裝:如全域例外、中介軟體體系等。
5. 社群相對較新:雖然成長迅速,但相比 Django 和 Flask,在某些特定場景下可能缺乏足夠的支援和資源。
6. CPU 密集型場景不如 Java:在 CPU 密集型場景下,Spring Boot(Java)憑藉 JIT 最佳化和執行緒池優勢,效能更穩定。
AI 模型部署:機器學習模型要對外提供服務,FastAPI 的高併發 + 自動文件兩個特性完美契合。某 AI 公司使用 FastAPI 部署模型預測服務,開發週期大幅縮短。
微服務架構:某電商平台使用 FastAPI 重構訂單服務後,開發週期從 6 週縮短至 2 週,錯誤率下降 72%,支援每秒 2000+ 的併發請求。
資料處理 API:需要對外提供資料查詢、統計、匯出等介面的場景。
即時應用:WebSocket 聊天、即時監控等需要雙向通訊的場景。
快速原型:需要快速驗證想法、展示 Demo 的場景。
大型企業級全端應用:如果需要強大的 Admin 後台、完善的 ORM、內建的使用者認證系統,Django 可能更合適。
CPU 密集型計算:複雜演算法、大資料處理等場景,Java(Spring Boot)憑藉 JIT 最佳化效能更穩定。
已有 Java 技術棧的團隊:如果團隊全是 Java 開發者,引入 Python 需要額外的學習成本和維運成本。
一位開發者做了一個真實的實驗:同一個業務服務,用 FastAPI 和 Spring Boot 各寫一遍,同時上線跑六個月。
開發階段:FastAPI 只用了 兩天 就把服務跑起來了,而 Spring Boot 那邊還在跟 Maven 依賴作戰。幾行程式碼就搞定了自動參數驗證、自動生成文件。
壓測階段(1000 併發使用者) :
FastAPI 在開發速度和首輪效能上全面領先。
但最終結果是 寫 Java 的同事贏了——不是因為效能,而是因為 維運體系、監控告警、日誌聚合、錯誤追蹤這些「非功能需求」,Spring Boot 的生態更成熟。
這個實驗告訴我們:技術選型不能只看開發速度和效能,還要看整個團隊的技術棧、維運體系和長期維護成本。
更多專案實戰在我的技術網站:susan.net.cn/project
FastAPI 不是一個要「取代」Spring Boot 的框架,而是一個在 特定場景下 能讓你事半功倍的工具。
如果你是 Java 開發者,遇到以下情況時,可以考慮把 FastAPI 加入你的技術工具箱:
如果你是完全的 Python 新手,FastAPI 可能是最好的入門框架之一——語法簡潔、文件優秀、社群活躍,而且能讓你快速看到成果。
技術選型沒有銀彈。
FastAPI 在 API 開發、微服務、AI 部署等場景下表現驚艷,但在大型企業級全端應用、CPU 密集型計算等場景下,Spring Boot 依然是更穩妥的選擇。
我的建議是:花一個週末把 FastAPI 跑一遍,寫一個完整的 CRUD 服務。感受一下「寫程式碼 = 寫文件」的體驗,體會一下「型別註解自動驗證」的便利。然後根據你的實際專案需求,決定是否引入正式環境。
畢竟,多一個趁手的工具,就多一條解決問題的路。
開源地址: