FastAPI Dependency Injection
FastAPI provides a powerful and concise dependency injection system.
Dependency injection is a design pattern that allows you to extract common logic (such as database connections, authentication, parameter validation, etc.) into reusable components, and then use them as needed in routes.

What is dependency injection
Simply put,DependencyIt is essentially a function that can use the same parameters as path operation functions (query parameters, path parameters, request body, etc.). FastAPI will automatically call the dependency function before executing the route function, and pass its return value to the route function.
Example
from fastapi import Depends, FastAPI
app = FastAPI()
# 1. Define the dependency function
def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
# 2. Use dependencies in routes
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
# commons receives the return value of the dependency function
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
# Multiple routes can reuse the same dependency
return commons
Code explanation:
| Part | Description |
|---|---|
common_parameters | Dependency functions, handling common query parameters |
Depends(common_parameters) | Declare parameterscommonsThe value comes from the dependency function |
commons: dict | Receives the dictionary returned by the dependency function |
Dependency functions and path operation functions use the same parameter declaration style, and FastAPI will automatically resolve the parameters of the dependency function. This means dependency functions can also use query parameters, path parameters, request body, etc.
Dependency execution flow
When a request arrives, FastAPI's processing order:
- Identify route functions and their dependencies
- Execute dependency functions (in dependency order)
- Pass the return value of the dependency function to the route function.
- Execute route function
Class as a dependency
Besides functions, you can also use classes as dependencies:
Example
from fastapi import Depends, FastAPI
app = FastAPI()
# Declaring Dependencies with Classes
class CommonQueryParams:
def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
# Use a class as a dependency
@app.get("/items/")
async def read_items(commons: Annotated[CommonQueryParams, Depends()]):
return {"q": commons.q, "skip": commons.skip, "limit": commons.limit}
WhenDepends()When no parameter is passed, FastAPI automatically uses the type annotation of the parameter (CommonQueryParams) as a dependency.
sub-dependency
Dependencies can have their own dependencies, forming a dependency chain:
Example
from fastapi import Depends, FastAPI
app = FastAPI()
# Dependency Functions
def query_extractor(q: str | None = None):
return q
# Sub-dependency: depends on query_extractor.
def query_checker(q: str = Depends(query_extractor)):
if q == "admin":
# Sub-dependencies can be validated
return q + " (checked)"
return q
# Routes use sub-dependencies
@app.get("/items/")
async def read_items(q: str = Depends(query_checker)):
return {"q": q}
Execution flow:query_extractor -> query_checker-> route function
Using dependencies in decorators
Sometimes you only need the side effects of the dependency (such as permission checks), not its return value. In the decorator'sdependenciesDeclared in parameters:
Example
app = FastAPI()
# Dependency: validate API Key
async def verify_api_key(x_api_key: str = Header()):
if x_api_key != "secret-key":
raise HTTPException(status_code=400, detail="X-API-Key invalid")
# Using dependency in decorator, no return value required
@app.get("/items/", dependencies=[Depends(verify_api_key)])
async def read_items():
return [{"item": "Foo"}]
# Apply dependency to the entire route group
@app.get("/users/", dependencies=[Depends(verify_api_key)])
async def read_users():
return [{"user": "Bar"}]
Global dependencies
You canFastAPIDeclare global dependencies on the instance, effective for all routes:
Example
async def verify_token(x_token: str = Header()):
if x_token != "fake-super-secret-token":
raise HTTPException(status_code=400, detail="X-Token header invalid")
# Global dependency: all routes need to pass token validation
app = FastAPI(dependencies=[Depends(verify_token)])
@app.get("/items/")
async def read_items():
return [{"item": "Foo"}]
@app.get("/users/")
async def read_users():
return [{"user": "Bar"}]
Dependencies using yield
When a dependency needs to perform cleanup operations (such as closing database connections), useyield:
Example
from fastapi import Depends, FastAPI
app = FastAPI()
# Dependencies that use yield: create a connection before the request, and close it after the request.
def get_db():
db = "database_connection" # Simulate creating a database connection
try:
yield db # Provide a database connection during request handling
finally:
print("Close database connection") # Clean up resources after request completes
@app.get("/items/")
async def read_items(db: str = Depends(get_db)):
return {"db": db}
Execution flow:
- When the request arrives, execute
yieldThe code before, creating a database connection yieldPass the connection to the route function- After the route function completes, execute
finallyCleanup code in block
yieldDependencies are ideal for managing resources that require cleanup, such as database connections and file handles. The cleanup code will execute regardless of whether the route function throws an exception.
Summary
- Dependency injection extracts common logic into reusable functions or classes.
- Usage
Depends()Declare dependencies in route function parameters - Dependencies can be nested, forming dependency chains
- decorator's
dependenciesParameters used for dependencies that don't need return values - Usage
yieldDependencies support resource cleanup - Global dependencies apply to all routes