Files
fastapi/docs/en/docs/tutorial/dependencies/sub-dependencies.md
Sebastián Ramírez 1f01ce9615 📝 Use Optional in docs (#1644)
* Updated .py files with Optional tag (up to body_nested_models)

* Update optionals

* docs_src/ all updates, few I was unsure of

* Updated markdown files with Optional param

* es: Add Optional typing to index.md

* Last of markdown files updated with Optional param

* Update highlight lines

* it: Add Optional typings

* README.md: Update with Optional typings

* Update more highlight increments

* Update highlights

* schema-extra-example.md: Update highlights

* updating highlighting on website to reflect .py changes

* Update highlighting for query-params & response-directly

* Address PR comments

* Get rid of unnecessary comment

*  Revert Optional in Chinese docs as it probably also requires changes in text

* 🎨 Apply format

*  Revert modified example

* ♻️ Simplify example in docs

* 📝 Update OpenAPI callback example to use Optional

*  Add Optional types to tests

* 📝 Update docs about query params, default to using Optional

* 🎨 Update code examples line highlighting

* 📝 Update nested models docs to use "type parameters" instead of "subtypes"

* 📝 Add notes about FastAPI usage of None

including:

= None

and

= Query(None)

and clarify relationship with Optional[str]

* 📝 Add note about response_model_by_alias

* ♻️ Simplify query param list example

* 🔥 Remove test for removed example

*  Update test for updated example

Co-authored-by: Christopher Nguyen <chrisngyn99@gmail.com>
Co-authored-by: yk396 <yk396@cornell.edu>
Co-authored-by: Kai Chen <kaichen120@gmail.com>
2020-06-28 20:13:30 +02:00

3.3 KiB

Sub-dependencies

You can create dependencies that have sub-dependencies.

They can be as deep as you need them to be.

FastAPI will take care of solving them.

First dependency "dependable"

You could create a first dependency ("dependable") like:

{!../../../docs_src/dependencies/tutorial005.py!}

It declares an optional query parameter q as a str, and then it just returns it.

This is quite simple (not very useful), but will help us focus on how the sub-dependencies work.

Second dependency, "dependable" and "dependant"

Then you can create another dependency function (a "dependable") that at the same time declares a dependency of its own (so it is a "dependant" too):

{!../../../docs_src/dependencies/tutorial005.py!}

Let's focus on the parameters declared:

  • Even though this function is a dependency ("dependable") itself, it also declares another dependency (it "depends" on something else).
    • It depends on the query_extractor, and assigns the value returned by it to the parameter q.
  • It also declares an optional last_query cookie, as a str.
    • Let's imagine that if the user didn't provide any query q, we just use the last query used, that we had saved to a cookie before.

Use the dependency

Then we can use the dependency with:

{!../../../docs_src/dependencies/tutorial005.py!}

!!! info Notice that we are only declaring one dependency in the path operation function, the query_or_cookie_extractor.

But **FastAPI** will know that it has to solve `query_extractor` first, to pass the results of that to `query_or_cookie_extractor` while calling it.
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

Using the same dependency multiple times

If one of your dependencies is declared multiple times for the same path operation, for example, multiple dependencies have a common sub-dependency, FastAPI will know to call that sub-dependency only once per request.

And it will save the returned value in a "cache" and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.

In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter use_cache=False when using Depends:

async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
    return {"fresh_value": fresh_value}

Recap

Apart from all the fancy words used here, the Dependency Injection system is quite simple.

Just functions that look the same as the path operation functions.

But still, it is very powerful, and allows you to declare arbitrarily deeply nested dependency "graphs" (trees).

!!! tip All this might not seem as useful with these simple examples.

But you will see how useful it is in the chapters about **security**.

And you will also see the amounts of code it will save you.