為什麼越來越多的人使用 FastAPI?

前言

--

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 到底是什麼?

1.1 一句話說清

FastAPI 是一個基於 Python 的現代 Web 框架,專為 建構高效能 API 而設計。

它由西班牙開發者 Sebastián Ramírez 於 2018 年建立,核心設計目標是解決傳統 Python Web 框架在效能、開發效率和型別安全方面的痛點。

它的技術定位可以概括為「三高」:高開發效率、高執行效能、高型別安全

1.2 跟 Java 開發者熟悉的框架對比

為了讓 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 穩重紮實,適合長途跋涉和複雜路況。

各有各的好,關鍵看你要做什麼。

1.3 FastAPI 到底能做什麼?

FastAPI 官方文件總結了它的核心能力:

高效能:基於 Starlette(非同步 Web 框架)和 Pydantic(高效能資料驗證),在 Python Web 框架中屬於效能天花板。

自動生成 API 文件:無需編寫文件,自動生成 Swagger UI(/docs)和 ReDoc(/redoc)。

使用 Python 型別提示自動驗證參數:自動請求參數驗證、自動回應模型驗證、IDE 自動補全體驗極佳。

原生非同步支援:完全支援 async/await,適合高併發 I/O 場景。

依賴注入系統:支援權限驗證、Token 驗證、DB 會話管理、統一行為注入。

易維護:型別提示 + 自動補全,適合微服務架構。

二、FastAPI 為什麼這麼快?

有些朋友可能會問:同樣是 Python 寫的,FastAPI 憑什麼比 Flask 快那麼多?

答案是三個字:ASGI

2.1 WSGI vs ASGI:一場革命

傳統的 Python Web 框架(如 Flask、Django)基於 WSGI(Web Server Gateway Interface)規範。

WSGI 是 同步 的——每個請求獨占一個執行緒,直到處理完才能釋放。這就好比一間餐廳裡,每個服務生一次只能服務一桌客人,其他客人只能乾等著。

而 FastAPI 基於 ASGI(Asynchronous Server Gateway Interface)規範。

ASGI 是 非同步非阻塞 的——每個請求在事件迴圈中被排程,而不是獨占執行緒資源。

這就像同一個服務生可以同時服務多桌客人——點完一桌的菜,趁廚房做菜的時間去幫另一桌點單,效率自然高出一大截。

這就是為什麼 FastAPI 能夠輕鬆處理 數千個併發連線

2.2 三引擎驅動架構

FastAPI 的架構可以概括為「星型模型」,由三個核心引擎驅動:

image.png

① 路由系統:基於路徑操作裝飾器(@app.get@app.post)實現 RESTful 路由,支援路徑參數和查詢參數的自動解析。其路徑匹配演算法採用正則表示式最佳化,在路徑參數較多時比 Flask 的 Werkzeug 路由 效能提升達 40%

② 依賴注入系統:透過 Depends 關鍵字實現服務依賴的自動解析,特別適合資料庫連線等資源的統一管理。其底層實現採用函式裝飾器模式,透過 __wrapped__ 屬性保留原始函式,在執行時動態注入依賴項。

③ 資料驗證引擎:FastAPI 的資料驗證基於 Pydantic 的 BaseModel,驗證流程包含欄位型別檢查、約束條件驗證、巢狀模型驗證和額外屬性檢查。

2.3 Pydantic 驗證流程

當一個請求到達 FastAPI 時,資料驗證的流程是這樣的:

image.png

如果在請求中傳入非字串型別的 username,框架會立即回傳 422 錯誤,並明確指出哪個欄位失敗及原因。

這種「在門口就把不合格的請求攔住」的設計,大大減少了業務程式碼裡的防禦性判斷。

2.4 效能數據

在 TechEmpower 基準測試中,FastAPI 在 JSON 序列化場景下達到 18,732 req/sec(同步模式)和 32,451 req/sec(非同步模式)

JSON 序列化效能達到 Django 的 8 倍,接近 Go 語言框架 Gin 的水準。

對於 API 開發來說,FastAPI 的速度大約是 Flask 的 2-3 倍

在 I/O 密集型場景下,這個差距會更加明顯。

三、環境建置:5 分鐘跑起來

3.1 安裝 Python 環境

建議使用 Python 3.9+ 版本:

bash 代碼解讀複製代碼# 使用 pyenv 管理 Python 版本(推薦)
brew install pyenv
pyenv install 3.11.5
pyenv global 3.11.5

# 或直接使用系統 Python
python3 --version

3.2 建立專案並安裝依賴

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。

3.3 撰寫第一個 API

建立 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}!"}

3.4 啟動服務

bash 代碼解讀複製代碼uvicorn main:app --reload --host 0.0.0.0 --port 8000

參數說明:

  • main:app —— main.py 檔案中的 app 實例
  • --reload —— 開發模式下自動重啟(正式環境不要用)
  • --host —— 監聽位址
  • --port —— 埠號

啟動後,訪問以下地址:

訪問 /docs 你會看到一份互動式的 API 文件——你什麼都沒寫,文件已經自動生成了。這就是 FastAPI 最讓人驚艷的特性之一。

四、核心概念實戰

4.1 路徑參數與查詢參數

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 中擷取,有預設值的參數是可選的
  • 型別註解讓 IDE 能提供自動補全,也讓框架能自動驗證

訪問範例:

  • GET /users/123{"user_id": 123, "name": "User_123"}
  • GET /items?skip=5&limit=20&category=books

4.2 請求主體與 Pydantic 模型

這是 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 會自動回傳 422 錯誤並說明原因

這就是「宣告式程式設計」的魅力——你只需要宣告「我要什麼」,框架幫你處理「怎麼驗證」。

4.3 依賴注入

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) 將依賴注入到路由函式中
  • 如果驗證失敗,自動回傳 401 錯誤
  • 驗證通過後,回傳的使用者資訊會作為 user 參數傳入路由函式

這種設計讓 認證邏輯和業務邏輯完全分離,程式碼更清晰、更可測試。

4.4 非同步支援

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 等待,期間事件迴圈可以處理其他請求
  • 對於 CPU 密集型操作,使用 asyncio.to_thread 放到執行緒池執行,避免阻塞事件迴圈

五、資料庫整合

5.1 非同步 SQLAlchemy 整合

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 是一個依賴,每個請求建立一個資料庫會話,請求結束後自動關閉
  • 所有資料庫操作都是非同步的,不會阻塞事件迴圈

六、統一回應與例外處理

在正式環境中,統一的回應格式和例外處理是必不可少的。

6.1 統一回應模型

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)

6.2 全域例外處理

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 模型和型別註解,自動生成兩份文件:

  • Swagger UI/docs):互動式文件,可以線上除錯 API
  • ReDoc/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 最佳化和執行緒池優勢,效能更穩定。

十、用一張圖看懂適用場景

image.png

最佳使用場景

AI 模型部署:機器學習模型要對外提供服務,FastAPI 的高併發 + 自動文件兩個特性完美契合。某 AI 公司使用 FastAPI 部署模型預測服務,開發週期大幅縮短。

微服務架構:某電商平台使用 FastAPI 重構訂單服務後,開發週期從 6 週縮短至 2 週,錯誤率下降 72%,支援每秒 2000+ 的併發請求。

資料處理 API:需要對外提供資料查詢、統計、匯出等介面的場景。

即時應用:WebSocket 聊天、即時監控等需要雙向通訊的場景。

快速原型:需要快速驗證想法、展示 Demo 的場景。

不太適合的場景

大型企業級全端應用:如果需要強大的 Admin 後台、完善的 ORM、內建的使用者認證系統,Django 可能更合適。

CPU 密集型計算:複雜演算法、大資料處理等場景,Java(Spring Boot)憑藉 JIT 最佳化效能更穩定。

已有 Java 技術棧的團隊:如果團隊全是 Java 開發者,引入 Python 需要額外的學習成本和維運成本。

十一、和 Spring Boot 的真實對比

一位開發者做了一個真實的實驗:同一個業務服務,用 FastAPI 和 Spring Boot 各寫一遍,同時上線跑六個月。

開發階段:FastAPI 只用了 兩天 就把服務跑起來了,而 Spring Boot 那邊還在跟 Maven 依賴作戰。幾行程式碼就搞定了自動參數驗證、自動生成文件。

壓測階段(1000 併發使用者)

  • FastAPI:回應時間 50 分位 45ms,吞吐量 2400 次/秒,記憶體占用 180MB
  • Spring Boot:回應時間 50 分位 80ms,吞吐量 1800 次/秒

FastAPI 在開發速度和首輪效能上全面領先。

但最終結果是 寫 Java 的同事贏了——不是因為效能,而是因為 維運體系、監控告警、日誌聚合、錯誤追蹤這些「非功能需求」,Spring Boot 的生態更成熟。

這個實驗告訴我們:技術選型不能只看開發速度和效能,還要看整個團隊的技術棧、維運體系和長期維護成本。

更多專案實戰在我的技術網站:susan.net.cn/project

十二、寫在最後

FastAPI 不是一個要「取代」Spring Boot 的框架,而是一個在 特定場景下 能讓你事半功倍的工具。

如果你是 Java 開發者,遇到以下情況時,可以考慮把 FastAPI 加入你的技術工具箱:

  • 需要快速部署一個 AI 模型推論服務
  • 需要搭建一個高效能的資料 API
  • 需要快速驗證一個產品原型
  • 團隊中已經有 Python 能力

如果你是完全的 Python 新手,FastAPI 可能是最好的入門框架之一——語法簡潔、文件優秀、社群活躍,而且能讓你快速看到成果。

技術選型沒有銀彈。

FastAPI 在 API 開發、微服務、AI 部署等場景下表現驚艷,但在大型企業級全端應用、CPU 密集型計算等場景下,Spring Boot 依然是更穩妥的選擇。

我的建議是:花一個週末把 FastAPI 跑一遍,寫一個完整的 CRUD 服務。感受一下「寫程式碼 = 寫文件」的體驗,體會一下「型別註解自動驗證」的便利。然後根據你的實際專案需求,決定是否引入正式環境。

畢竟,多一個趁手的工具,就多一條解決問題的路

開源地址


原文出處:https://juejin.cn/post/7656613897318907958


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝15   💬3   ❤️3
629
🥈
我愛JS
📝2   💬3   ❤️3
116
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登