
Module 6 Exercises: Mastering Dependency Injection
Practical exercises to harden your skills in creating shared services, authentication guards, and dependency chains.
Module 6 Exercises: Mastering Dependency Injection
Dependency Injection is what makes FastAPI feel like "Magic." These exercises will help you understand how to control that magic to build clean, maintainable systems.
Exercise 1: The Request ID Logger
Design a dependency called get_request_id. It should:
- Look for a header named
X-Request-ID. - If the header exists, return it.
- If it doesn't exist, return a default string
"GENERIC-ID".
Goal: Show how you would inject this into a GET /status endpoint.
Exercise 2: The Multi-Layer Chain
You are building a Payment Gateway. Design a chain of three dependencies:
get_user: Fetches a user model from the DB.check_active_card: Depends onget_userand checks if the user has a valid credit card on file.require_funds: Depends oncheck_active_cardand checks if the user's balance is above $10.00.
How would you apply require_funds to a POST /buy-coffee endpoint?
Exercise 3: Dependency Overrides
In your tests, you want to replace the get_db dependency (which connects to a real Postgres database) with a get_test_db function (which uses an in-memory SQLite database).
Write the single line of code needed to tell your FastAPI app to perform this override.
Self-Correction / Discussion
Exercise 1 Answer:
from fastapi import Header, Depends
async def get_request_id(x_request_id: str | None = Header(None)):
return x_request_id or "GENERIC-ID"
@app.get("/status")
async def check_status(rid: str = Depends(get_request_id)):
return {"status": "ok", "request_id": rid}
Exercise 2 Answer:
@app.post("/buy-coffee")
async def buy_coffee(user: User = Depends(require_funds)):
# Your payment logic here
return {"message": "Success"}
Exercise 3 Answer:
app.dependency_overrides[get_db] = get_test_db
Summary of Module 6
You have unlocked FastAPI's most powerful architectural tool.
- Separation of Concerns: Your routes only care about logic; your dependencies care about resources.
- Testability: You can swap real services for mocks in one line.
- Modularity: You can build complex checks by nesting dependencies.
In Module 7: Error Handling and Responses, we will learn how to make our API communicate failures as clearly as it communicates successes.