ミドルウェア¶
ミドルウェアは、リクエストがエンドポイントに届く前と、レスポンスがクライアントに返る前に処理を挟み込める仕組み。
認証チェックや CORS、 CSRF 対策 のように、複数のエンドポイントに共通でかけたい処理を書くのに向いてる。
cf. https://fastapi.tiangolo.com/tutorial/middleware/
どういう流れで動くのか¶
ミドルウェアは「リクエストを受け取る → 次の処理に渡す → レスポンスを受け取る」という順番で動く。
call_next を呼ぶと、その先のミドルウェアやエンドポイントに処理が渡って、戻ってきたレスポンスを受け取れる。
下の例は、リクエストの処理にかかった時間を測ってレスポンスヘッダーに入れるミドルウェア( FastAPI チュートリアルと同じもの )。
# main.py
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start = time.perf_counter()
response = await call_next(request) # 先の処理にリクエストを渡す
elapsed = time.perf_counter() - start
response.headers["X-Process-Time"] = str(elapsed) # 返ってきたレスポンスに手を加える
return response
@app.middleware("http") を付けると、全リクエストがこの関数を通る。引数の request が届いたリクエストで、 call_next が「この先の処理を実行して」という関数。
ポイントは call_next を境に処理が「行き」と「帰り」に分かれること。
- 行き(
call_nextの前 ): まだエンドポイントには渡してない段階。ここでは開始時刻を記録してる。 await call_next(request): ここで初めてエンドポイントに処理が渡る。awaitで処理が終わるのを待って、結果のレスポンスを受け取る。- 帰り(
call_nextの後 ): 返ってきたレスポンスに手を加えられる。ここではかかった時間を計算して、X-Process-Timeヘッダーに入れてる。
認証チェックみたいに「エンドポイントに入る前に弾きたい」処理は行きに、レスポンスの加工は帰りに書く、というイメージ。
複数のミドルウェアを登録すると、玉ねぎのように外側から内側へ入って、内側から外側へ戻ってくる。
FastAPI の内部の仕組み¶
ミドルウェアが内部でどう動いてるかは、 Marcelo Trylesinski さんの PyCon Italia 2024 のトークで説明されてる。