FastAPI 中間件 (Middleware)
Middleware 是一個函數,它會在每個 請求 (Request) 被特定的路徑操作處理之前,以及每個 回應 (Response) 回傳之前執行。
Middleware 位於應用程式與客戶端之間,就像一道門戶。
它可以做的事情包括:
- 在請求到達路徑操作之前,修改請求物件 (例如:添加 Header)。
- 在回應回傳給客戶端之前,修改回應物件。
- 計算請求處理時間 (Process Time)。
- 攔截錯誤。
建立 Middleware
要建立 Middleware,你需要定義一個包含 request 和 call_next 參數的非同步函數,並使用 @app.middleware("http") 裝飾器。
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
# 1. 請求處理前 (Before Request)
start_time = time.time()
# 2. 呼叫下一個處理流程 (可能是路徑操作,或是下一個 Middleware)
response = await call_next(request)
# 3. 回應處理後 (After Response)
process_time = time.time() - start_time
# 修改回應:加入自訂 Header
response.headers["X-Process-Time"] = str(process_time)
return response
@app.get("/")
async def main():
return {"message": "Hello World"}
在這個範例中:
- 我們記錄了開始時間。
await call_next(request)會把請求傳遞下去,直到拿到回應。- 計算總共花費的時間。
- 將時間寫入 Response Header
X-Process-Time。
常用的內建 Middleware
FastAPI (實際上是 Starlette) 內建了許多好用的 Middleware。
TrustedHostMiddleware
限制只能透過特定的 Host Name (網域名稱) 存取 API,防止 HTTP Host Header 攻擊。
from fastapi.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=["example.com", "*.example.com"],
)
GZipMiddleware
自動對回應內容進行 GZip 壓縮,減少傳輸量。
from fastapi.middleware.gzip import GZipMiddleware
app = FastAPI()
app.add_middleware(GZipMiddleware, minimum_size=1000)
HTTPSRedirectMiddleware
強制將所有 HTTP 請求重定向到 HTTPS。
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)
CORS Middleware
這可能是最常用的一個。由於瀏覽器的安全性限制 (同源政策),前端網頁 (如跑在 localhost:3000) 預設不能呼叫不同源的 API (如 localhost:8000)。
我們將在 CORS 文章中專門介紹如何設定 CORS。
總結
- 使用
@app.middleware("http")來自訂 Middleware。 - Middleware 可以攔截並修改 Request 和 Response。
- 利用
add_middleware來加入現成的第三方 Middleware。