中介軟體¶
你可以在 FastAPI 應用程式中加入中介軟體。
「中介軟體」是一個函式,在任何特定的路徑操作處理之前先處理每個請求;在回傳之前,也會處理每個回應。
- 它會攔截進到應用程式的每個請求。
- 然後可以對該請求做一些處理或執行所需的程式碼。
- 接著把請求傳遞給應用程式的其餘部分(某個路徑操作)處理。
- 之後再接收應用程式(某個路徑操作)所產生的回應。
- 可以對該回應做一些處理或執行所需的程式碼。
- 然後回傳回應。
建立中介軟體¶
要建立中介軟體,將裝飾器 @app.middleware("http") 加在函式上方。
中介軟體函式會接收:
request。- 一個函式
call_next,會以request作為參數。- 這個函式會把
request傳給對應的路徑操作。 - 然後回傳對應路徑操作所產生的
response。
- 這個函式會把
- 然後你可以在回傳之前進一步修改
response。
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
🤓 Other versions and variants
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
Tip
請記得,自訂的非標準標頭可以使用 X- 前綴。
但如果你有自訂標頭並希望瀏覽器端的用戶端能看到它們,你需要在 CORS 設定(CORS(Cross-Origin Resource Sharing))中使用 Starlette 的 CORS 文件所記載的參數 expose_headers 將它們加入。
技術細節
你也可以使用 from starlette.requests import Request。
FastAPI 為了方便開發者而提供了它,但實際上它直接來自 Starlette。
在 response 之前與之後¶
你可以在任何路徑操作接收 request 之前,加入要執行的程式碼。
也可以在產生出 response 之後、回傳之前執行程式碼。
例如,你可以新增一個自訂標頭 X-Process-Time,其內容為處理請求並產生回應所花費的秒數:
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
🤓 Other versions and variants
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
Tip
這裡我們使用 time.perf_counter() 而不是 time.time(),因為在這些用例中它可能更精確。🤓
多個中介軟體的執行順序¶
當你使用 @app.middleware() 裝飾器或 app.add_middleware() 方法加入多個中介軟體時,每個新的中介軟體都會包裹應用程式,形成一個堆疊。最後加入的中介軟體位於最外層,最先加入的位於最內層。
在請求路徑上,最外層的中介軟體最先執行。
在回應路徑上,它最後執行。
例如:
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
執行順序如下:
-
請求:MiddlewareB → MiddlewareA → 路由
-
回應:路由 → MiddlewareA → MiddlewareB
這種堆疊行為可確保中介軟體以可預期且可控制的順序執行。
其他中介軟體¶
你之後可以在進階使用者指南:進階中介軟體閱讀更多關於其他中介軟體的內容。
下一節你將會讀到如何使用中介軟體處理 CORS。