DEV Community

Cover image for Day 4: Mastering Dependency Injection with `Depends()` in FastAPI
Utkarsh Rastogi
Utkarsh Rastogi

Posted on • Edited on

Day 4: Mastering Dependency Injection with `Depends()` in FastAPI

Welcome to Day 4 of our FastAPI journey! Yesterday, we explored how to use Request Bodies and Pydantic to validate data like a pro.

Today, we step into the powerful world of Dependency Injection β€” and why FastAPI’s Depends() makes our code cleaner, reusable, and more secure.


🧠 What Is Dependency Injection (DI)?

Imagine you're building an app where every route requires API key validation, or pagination logic, or even a database session.

Instead of repeating the same logic in every route, you can inject it once using Depends() β€” and FastAPI handles it for you!


🎯 Real-World Analogy: Depends() is Your Personal Assistant

Let’s say you run a restaurant. Instead of you greeting customers, validating reservations, and serving them every time…

You delegate those tasks to trusted staff β€” that’s Dependency Injection!

In FastAPI:

  • Your function = the restaurant
  • The Depends() function = your assistant (API key checker, paginator, etc.)
  • FastAPI = your efficient manager

πŸ”§ Step-by-Step: Basic Dependency Injection

πŸ“ Create a file called di_app.py

from fastapi import FastAPI, Depends

app = FastAPI()

# Step 1: Create a dependency function
def say_hello():
    return "Hello from a dependency!"

# Step 2: Inject it using Depends
@app.get("/")
def read_root(greeting: str = Depends(say_hello)):
    return {"message": greeting}
Enter fullscreen mode Exit fullscreen mode

πŸš€ Test Your Endpoint

πŸ–₯️ Start the FastAPI server:

uvicorn di_app:app --host 0.0.0.0 --reload --port 9005
Enter fullscreen mode Exit fullscreen mode

🌐 Open your browser:

http://localhost:9005/

Output:

Output

βœ… Try it β€” FastAPI will automatically call say_hello() and inject its return value.


πŸ” Add Security – API Key Validation

Let’s say every route must check if a valid API key is present in the request headers.

We can use FastAPI’s Depends() along with Header to inject and validate the API key for any endpoint.

Here's how you define a reusable dependency function to validate the API key:

from fastapi import Header, HTTPException

API_KEY = "mysecret"

def verify_api_key(x_api_key: str = Header(...)):
    if x_api_key != API_KEY:
        raise HTTPException(status_code=401, detail="Invalid API Key")

@app.get("/secure")
def secure_data(_ = Depends(verify_api_key)):
    return {"data": "Top secret info!"}
Enter fullscreen mode Exit fullscreen mode

πŸš€ Test Your Endpoint

πŸ–₯️ Start the FastAPI server:

uvicorn di_app:app --host 0.0.0.0 --reload --port 9005
Enter fullscreen mode Exit fullscreen mode

🌐 Open your browser and visit the interactive docs:

http://localhost:9005/docs

Input Secret

Output:

Output Secret


πŸ”„ Reusable Pagination Logic

Sometimes, you want to apply the same pagination logic to multiple endpoints (e.g., skip and limit query parameters).

Instead of repeating the parameters in every route, you can use FastAPI’s Depends() to inject reusable logic β€” keeping your code clean and DRY.

βœ… Define a Reusable Pagination Dependency

from fastapi import Depends, FastAPI

app = FastAPI()

def pagination(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

@app.get("/items")
def get_items(paging: dict = Depends(pagination)):
    return {"pagination": paging}

Enter fullscreen mode Exit fullscreen mode

🧠 Explanation:

  • pagination() is a simple function that takes skip and limit as query parameters with default values.
  • Depends(pagination) injects those values into your route as a dictionary.
  • You can reuse pagination() in any route that supports pagination β€” no duplication!

πŸš€ Test Your Endpoint

πŸ–₯️ Start the FastAPI server:

uvicorn di_app:app --host 0.0.0.0 --reload --port 9005
Enter fullscreen mode Exit fullscreen mode

🌐 Open your browser:

http://localhost:9005/items?skip=5&limit=15

Output:

limit

This pattern is perfect for **list-based APIs like /users, /posts, /products, and more β€” where consistent pagination behavior is needed.**


🧠 Recap

Feature How It Helps
Depends() Inject shared logic (API key, DB session, etc.)
Header validation Use Header + Depends() for auth checks
Query params as dependencies Reuse pagination, filtering, etc. in multiple routes

🌍 Real-World Use Cases

Use Case Dependency Function Example
API Key Auth Validate headers
Pagination Reuse skip and limit parameters
Database session Inject DB connection using SQLAlchemy
Logging / Metrics Record every request
User authentication Get current user from JWT or session

πŸ™ Credits

Huge thanks to the FastAPI Official Documentation by SebastiΓ‘n RamΓ­rez (@tiangolo) β€” the best place to learn and explore everything about FastAPI.


πŸ‘¨β€πŸ’» About Me

Hey there! I’m Utkarsh Rastogi, an AWS Community Builder and passionate cloud-native enthusiast who loves building scalable backend systems and sharing knowledge with the community.

πŸ”— Connect with me: Utkarsh Rastogi


πŸ’¬ Share Your Thoughts – I'd Love Your Feedback!

If you enjoyed today's post or learned something new, I'd truly appreciate it if you leave a comment or share your thoughts πŸ‘‡

Your feedback, questions, or even a quick β€œπŸ”₯ Loved this!” keeps me motivated to continue this journey and share more in the upcoming #FastAPIDaily posts.

βœ… What did you find most helpful?

βœ… Anything you'd like explained in the next part?

βœ… Suggestions for improvement? I’m all ears! πŸ™Œ

Let’s grow and learn together β€” one FastAPI day at a time πŸš€


Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.