Dependency injection helps your code stay clean and easy to change. It lets you give parts of your app what they need without hard coding them inside.
Why dependency injection matters in FastAPI
Start learning this pattern below
Jump into concepts and practice - no test required
from fastapi import Depends app = FastAPI() def get_db(): db = create_db_session() try: yield db finally: db.close() @app.get("/items/") async def read_items(db = Depends(get_db)): return db.query_items()
Depends() tells FastAPI to run the function and give its result to your endpoint.
You can use yield in dependency functions to handle setup and cleanup.
from fastapi import Depends, HTTPException app = FastAPI() def get_token_header(): token = "expected-token" if token != "expected-token": raise HTTPException(status_code=400, detail="Invalid token") return token @app.get("/secure-data") async def secure_data(token: str = Depends(get_token_header)): return {"data": "This is secure"}
from fastapi import Depends app = FastAPI() class Service: def do_work(self): return "work done" def get_service(): return Service() @app.get("/work") async def work(service: Service = Depends(get_service)): return {"result": service.do_work()}
This simple FastAPI app shows how dependency injection passes a message to the endpoint without hard coding it inside.
from fastapi import FastAPI, Depends app = FastAPI() # Dependency function async def get_message(): return "Hello from dependency!" # Endpoint using dependency injection @app.get("/greet") async def greet(message: str = Depends(get_message)): return {"message": message}
Dependencies can be reused in many endpoints to avoid repeating code.
Using dependency injection makes testing easier by allowing you to swap real parts with mocks.
FastAPI handles calling and cleaning up dependencies automatically.
Dependency injection helps keep your code clean and flexible.
It allows easy sharing and swapping of parts like services or database connections.
FastAPI makes using dependency injection simple with the Depends function.
Practice
Solution
Step 1: Understand the purpose of dependency injection
Dependency injection allows you to provide parts like services or database connections to your functions without hardcoding them.Step 2: Recognize benefits in FastAPI
This makes your code cleaner and more flexible, as you can easily swap or share components.Final Answer:
It helps keep code clean and makes components easy to share or replace. -> Option DQuick Check:
Dependency injection = clean, flexible code [OK]
- Confusing dependency injection with caching
- Thinking it generates HTML automatically
- Believing it forces monolithic code
Solution
Step 1: Recall FastAPI dependency syntax
FastAPI uses Depends() inside the function parameter default value to declare dependencies.Step 2: Check each option
def read_data(db = Depends(get_db)): correctly uses db = Depends(get_db). Others misuse type hints or call the function directly.Final Answer:
def read_data(db = Depends(get_db)): -> Option AQuick Check:
Depends() in default value = correct syntax [OK]
- Calling the dependency function instead of passing it
- Using Depends as a type hint incorrectly
- Assigning dependency without Depends()
from fastapi import FastAPI, Depends
app = FastAPI()
def get_number():
return 42
@app.get("/number")
def read_number(num: int = Depends(get_number)):
print(f"Number is {num}")
return {"number": num}Solution
Step 1: Understand dependency injection behavior
The get_number function returns 42 and is injected as the parameter num.Step 2: Trace the endpoint execution
When the endpoint is called, it prints "Number is 42" and returns JSON with number 42.Final Answer:
Number is 42 printed in console, response JSON {"number": 42} -> Option AQuick Check:
Depends injects 42, prints and returns it [OK]
- Thinking dependency must be async
- Expecting default 0 instead of injected value
- Confusing print output with response content
def get_db():
return "db_connection"
@app.get("/items")
def read_items(db = get_db()):
return {"db": db}Solution
Step 1: Identify how dependency should be declared
Dependencies must be passed as Depends(get_db), not by calling get_db() directly.Step 2: Explain the problem in the code
Calling get_db() runs it once at startup, not per request, losing flexibility and benefits of injection.Final Answer:
The dependency function is called immediately instead of injected. -> Option BQuick Check:
Call vs Depends() matters for injection [OK]
- Calling dependency function instead of passing Depends()
- Confusing async requirement with dependency injection
- Ignoring missing return statement (it exists here)
Solution
Step 1: Understand lifecycle management with dependencies
Using yield in a dependency function allows setup before yield and cleanup after the request finishes.Step 2: Compare options for connection management
Use a dependency function with yield that opens the connection, yields it, then closes it after. correctly manages connection per request lifecycle. Others either create global state or misuse parameters.Final Answer:
Use a dependency function with yield that opens the connection, yields it, then closes it after. -> Option CQuick Check:
Yield in dependency = setup and cleanup per request [OK]
- Using global connection risking concurrency issues
- Calling connection directly losing cleanup control
- Passing connection via query parameters insecurely
