The Superpower: Dependency Injection
The Superpower: Dependency Injection
Section titled “The Superpower: Dependency Injection”What is Dependency Injection?
Section titled “What is Dependency Injection?”Dependency Injection (DI) system is widely considered FastAPI’s most powerful and useful feature. In software engineering, DI is a design pattern that allows a program to remove hard-coded dependencies and make it possible to change them, often to facilitate testing.
In many frameworks (like Java’s Spring), DI can be complex and verbose. FastAPI makes it incredibly simple. You don’t need to create classes or register containers. In FastAPI, a dependency is just a function (or a class) that provides data or logic to your path operations.
Creating and Using Dependencies
Section titled “Creating and Using Dependencies”Imagine you have query parameters for pagination (skip and limit) that you use in many different endpoints. Instead of rewriting the arguments in every path operation, you can define them once in a function.
from typing import Annotatedfrom fastapi import Depends, FastAPI
app = FastAPI()
# 1. Create the dependency functionasync def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100): return {"q": q, "skip": skip, "limit": limit}
# 2. Inject it into the path operation@app.get("/items/")async def read_items(commons: Annotated[dict, Depends(common_parameters)]): return commons
@app.get("/users/")async def read_users(commons: Annotated[dict, Depends(common_parameters)]): return commonsWhen a request hits /items/, FastAPI sees the Depends(common_parameters):
- It calls
common_parameters. - It passes the query parameters (
q,skip,limit) to that function. - It takes the result returned by
common_parameters. - It assigns that result to the
commonsparameter in your path operation.
Sub-dependencies
Section titled “Sub-dependencies”FastAPI allows you to build graphs of dependencies. A dependency function can itself use Depends to require other dependencies.
For example, you might have a dependency get_token that extracts a header. Then, a dependency get_user that depends on get_token to find the user. Finally, your path operation depends on get_user. FastAPI handles this entire chain automatically.
Dependencies with yield
Section titled “Dependencies with yield”Sometimes you need to perform an action after the request has been processed, such as closing a database connection or a file. FastAPI supports this via the yield keyword.
This is very similar to Python’s Context Managers (with statements). The code before yield runs before the request processing, and the code after yield runs after the response is sent.
async def get_db(): db = DBSession() try: yield db finally: # This runs after the request is finished db.close()By using yield, you ensure that resources are properly cleaned up, even if an exception occurs during the request processing.