はじめに
エミもふ白菜さん nikkieです。
FastAPIでDBのセッションをDependsで渡すのを見ます1。
これがリクエストごとに実行されていることを、簡単な例で確認しました。
目次
Tutorial「Dependencies」の例
path operation関数2が依存するパラメタを引数で注入する例です。
2つのpath operation関数に共通する依存を注入しています
Dependsに渡す関数にprintを仕込みました。
呼び出されるタイミングを確認する意図です。
% uv version uv 0.5.17 (Homebrew 2025-01-10) % uvx --with 'fastapi[standard]' fastapi dev first_steps.py
% curl http://127.0.0.1:8000/items/
{"q":null,"skip":0,"limit":100}
common_parameters called
INFO 127.0.0.1:54804 - "GET /items/ HTTP/1.1"
200
% curl http://127.0.0.1:8000/users/
{"q":null,"skip":0,"limit":100}
common_parameters called
INFO 127.0.0.1:54818 - "GET /users/ HTTP/1.1"
200
リクエストのたびにcommon_parametersが呼び出されていることが分かります。
それぞれのパスに複数回リクエストを送って確認しています。
typing.Annotated
CommonsDep = Annotated[dict, Depends(common_parameters)]
https://docs.python.org/ja/3/library/typing.html#typing.Annotated
Add metadata x to a given type T by using the annotation Annotated[T, x].
これは型にメタデータを与えるものでした。
common_parametersの例では、dict型にDepends(common_parameters)というメタデータを与えています。
仕組みはいまは見当がつかず、まるで魔法のようですが、FastAPIのDependsはメタデータの関数を実行して返り値を注入しているのですね。
終わりに
FastAPIでDependsに指定した関数が、path operation関数を呼び出すごと(=リクエストごと)に実行されることを確認しました。
DependsでDBセッションを渡す場合、リクエストごとにセッションが作られるということですね3
- めちゃめちゃ参考にしているリポジトリの例 https://github.com/rhoboro/async-fastapi-sqlalchemy/blob/12683934b451c76af5eea7ee5bf4e6c8342ca165/app/api/notes/use_cases.py#L9-L11 (sub-dependenciesまで関わるので、直感的ではないかもですが)↩
- ドキュメント中の用語です https://fastapi.tiangolo.com/tutorial/first-steps/#step-4-define-the-path-operation-function↩
- DBセッションの作り方を扱ったこちらの記事とつながります ↩