ミドルウェア¶
FastAPI アプリケーションにミドルウェアを追加できます。
「ミドルウェア」は、特定のパス操作によって処理される前にすべてのリクエストを処理する関数です。また、返す前にすべてのレスポンスも処理します。
- アプリケーションに届くすべてのリクエストを受け取ります。
- そのリクエストに対して何かをしたり、必要なコードを実行したりできます。
- その後、そのリクエストをアプリケーションの残りの部分 (何らかのパス操作) によって処理されるように渡します。
- その後、アプリケーション (何らかのパス操作) によって生成されたレスポンスを受け取ります。
- そのレスポンスに対して何かをしたり、必要なコードを実行したりできます。
- その後、レスポンスを返します。
技術的な詳細
yield を伴う依存関係がある場合、終了コードはミドルウェアの後に実行されます。
バックグラウンドタスク (「バックグラウンドタスク」セクションで説明します) がある場合、それらはすべてのミドルウェアの後に実行されます。
ミドルウェアを作成する¶
ミドルウェアを作成するには、関数の上にデコレーター @app.middleware("http") を使用します。
ミドルウェア関数は以下を受け取ります。
request。- パラメータとして
requestを受け取る関数call_next。 - その後、
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
ヒント
カスタムの独自のヘッダーはX- プレフィックスを使用して追加できることに注意してください。
しかし、ブラウザのクライアントに見せたいカスタムヘッダーがある場合は、Starlette の CORS ドキュメントに記載されているパラメータ expose_headers を使用して、CORS 設定 (CORS (Cross-Origin Resource Sharing)) に追加する必要があります。
技術的な詳細
from starlette.requests import Request も使用できます。
FastAPI は開発者にとっての利便性としてこれを提供していますが、Starlette から直接来ています。
response の前後¶
request が何らかのパス操作によって受け取られる前に、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
ヒント
ここでは、time.time() の代わりにtime.perf_counter() を使用しています。これらのユースケースではより正確になる可能性があるためです。 🤓
複数のミドルウェア実行順序¶
@app.middleware() デコレーターまたは app.add_middleware() メソッドのいずれかを使用して複数のミドルウェアを追加すると、各新しいミドルウェアがアプリケーションをラップし、スタックを形成します。最後に追加されたミドルウェアが最も外側になり、最初に追加されたミドルウェアが最も内側になります。
リクエストパスでは、最も外側のミドルウェアが最初に実行されます。
レスポンスパスでは、最後に実行されます。
例えば
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
これにより、以下の実行順序になります。
-
リクエスト: ミドルウェアB → ミドルウェアA → ルート
-
レスポンス: ルート → ミドルウェアA → ミドルウェアB
このスタック動作により、ミドルウェアが予測可能で制御可能な順序で実行されることが保証されます。
その他のミドルウェア¶
その他のミドルウェアについては、「高度なユーザーガイド: 高度なミドルウェア」で詳しく読むことができます。
次のセクションでは、ミドルウェアで CORS を処理する方法について説明します。