Dependency Injection in FastAPI
Key Concepts
1. What is Dependency Injection?
Dependency Injection (DI) is a design pattern that allows you to pass dependencies into your functions or classes rather than having them create their own dependencies. In FastAPI, DI is used to manage resources like database connections, authentication tokens, and other services in a clean and reusable way.
2. How Does Dependency Injection Work in FastAPI?
FastAPI uses the Depends
function to inject dependencies into your route handlers. When a request is made to a route that has dependencies, FastAPI automatically resolves and injects those dependencies before calling the route handler. This ensures that your route handlers remain clean and focused on their primary logic.
3. Benefits of Dependency Injection
Dependency Injection offers several benefits, including:
- Code Reusability: Dependencies can be reused across multiple routes, reducing redundancy.
- Testability: Dependencies can be easily mocked or replaced during testing.
- Separation of Concerns: Routes are not cluttered with dependency management code, making them easier to read and maintain.
Examples
Example 1: Basic Dependency Injection
In this example, we define a simple dependency that returns a user's name and inject it into a route handler.
from fastapi import FastAPI, Depends app = FastAPI() def get_user_name(): return "John Doe" @app.get("/user/") async def read_user(user_name: str = Depends(get_user_name)): return {"username": user_name}
Example 2: Dependency with Parameters
Here, we define a dependency that takes a parameter and returns a customized greeting message.
from fastapi import FastAPI, Depends app = FastAPI() def get_greeting(name: str): return f"Hello, {name}!" @app.get("/greet/{name}") async def greet(greeting: str = Depends(get_greeting)): return {"message": greeting}
Example 3: Nested Dependencies
In this example, we demonstrate nested dependencies where one dependency depends on another.
from fastapi import FastAPI, Depends app = FastAPI() def get_user_id(): return 123 def get_user_details(user_id: int = Depends(get_user_id)): return {"id": user_id, "name": "John Doe"} @app.get("/user/details") async def read_user_details(user_details = Depends(get_user_details)): return user_details
Analogies
Think of Dependency Injection as a butler in a mansion who handles all the logistics of serving guests. Instead of each guest (route handler) having to fetch their own food (dependencies), the butler (FastAPI) ensures that everything is prepared and delivered to them. This allows the guests to focus on enjoying their meal (handling the request) without worrying about the details of food preparation (dependency management).
Another analogy is a construction site where each worker (route handler) has a specific task. Instead of each worker having to gather their own tools (dependencies), a tool manager (FastAPI) ensures that the right tools are delivered to the workers at the right time. This streamlines the construction process and ensures that each worker can focus on their task.