5.8 KiB
Підзалежності
Ви можете створювати залежності, які мають підзалежності.
Вони можуть бути настільки глибокими, наскільки вам потрібно.
FastAPI подбає про їх розв’язання.
Перша залежність «dependable»
Ви можете створити першу залежність («dependable») так:
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
Вона оголошує необов’язковий query-параметр q як str, а потім просто повертає його.
Це доволі просто (не надто корисно), але допоможе нам зосередитися на тому, як працюють підзалежності.
Друга залежність, «dependable» і «dependant»
Далі ви можете створити іншу функцію залежності (тобто «dependable»), яка водночас оголошує власну залежність (тобто також є «dependant»):
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
Зосередьмося на оголошених параметрах:
- Хоча ця функція сама є залежністю («dependable»), вона також оголошує іншу залежність (вона «depends» від чогось іншого).
- Вона залежить від
query_extractorі присвоює значення, повернене ним, параметруq.
- Вона залежить від
- Вона також оголошує необов’язковий cookie
last_queryякstr.- Якщо користувач не надав жодного query
q, ми використовуємо останній використаний запит, який раніше зберегли в cookie.
- Якщо користувач не надав жодного query
Використання залежності
Тоді ми можемо використати залежність так:
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
/// info | Інформація
Зверніть увагу, що ми оголошуємо лише одну залежність у функції операції шляху — query_or_cookie_extractor.
Але FastAPI знатиме, що спочатку потрібно розв’язати query_extractor, щоб передати його результат у query_or_cookie_extractor під час виклику.
///
graph TB
query_extractor(["query_extractor"])
query_or_cookie_extractor(["query_or_cookie_extractor"])
read_query["/items/"]
query_extractor --> query_or_cookie_extractor --> read_query
Використання однієї залежності кілька разів
Якщо одну з ваших залежностей оголошено кілька разів для тієї самої операції шляху (наприклад, кілька залежностей мають спільну підзалежність), FastAPI знатиме, що цю підзалежність потрібно викликати лише один раз на запит.
І він збереже повернене значення в «cache» та передасть його всім «dependants», яким воно потрібно в межах цього запиту, замість виклику залежності кілька разів для одного й того самого запиту.
У просунутому сценарії, коли ви знаєте, що залежність має викликатися на кожному кроці (можливо, кілька разів) у межах одного запиту, замість використання «cached» значення, ви можете встановити параметр use_cache=False під час використання Depends:
//// tab | Python 3.9+
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
return {"fresh_value": fresh_value}
////
//// tab | Python 3.9+ без Annotated
/// tip | Порада
За можливості надавайте перевагу версії з Annotated.
///
async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
return {"fresh_value": fresh_value}
////
Підсумок
Окрім усіх «модних» слів, використаних тут, система Dependency Injection доволі проста.
Це просто функції, що виглядають так само, як і функції операцій шляху.
Але водночас вона дуже потужна й дозволяє оголошувати довільно глибоко вкладені «графи» залежностей (дерева).
/// tip | Порада
Може здаватися, що з цими простими прикладами все це не надто корисно.
Але ви побачите, наскільки це корисно, у розділах про security.
І також побачите, скільки коду це вам зекономить.
///