Monday, 22 December 2025

FastAPI Dependency Injection Explained with Examples

Dependency Injection (DI) is one of the most powerful features of FastAPI, yet it’s also one of the most confusing topics for beginners.

If you are coming from Spring Boot, you may think:

“Where is @Autowired in FastAPI?”

In this post, we’ll explain FastAPI Dependency Injection in simple terms, with real-world examples and best practices.


What Is Dependency Injection?

Dependency Injection means:

Passing required objects (dependencies) into a function instead of creating them inside the function.

Why it matters

  • Cleaner code

  • Better reusability

  • Easier testing

  • Loose coupling


Dependency Injection in FastAPI

FastAPI provides dependency injection using the Depends() function.

It allows you to:

  • Inject database connections

  • Inject authentication logic

  • Inject services

  • Share common logic across APIs


Basic Dependency Injection Example

Simple dependency function

from fastapi import Depends def get_message(): return "Hello from dependency"

Using it in an API

from fastapi import FastAPI, Depends app = FastAPI() @app.get("/hello") def hello(message: str = Depends(get_message)): return {"message": message}

📌 FastAPI automatically:

  • Calls get_message()

  • Injects the returned value

  • Manages execution order


Dependency Injection vs Normal Function Call

❌ Without DI:

@app.get("/users") def get_users(): db = create_db_connection() return db.fetch_users()

✅ With DI:

def get_db(): return create_db_connection() @app.get("/users") def get_users(db = Depends(get_db)): return db.fetch_users()

✔ Cleaner
✔ Reusable
✔ Test-friendly


Real-World Example: Database Dependency

Database session dependency

def get_db(): db = DBSession() try: yield db finally: db.close()

Injecting DB into API

@app.get("/users") def get_users(db = Depends(get_db)): return db.get_all_users()

📌 FastAPI handles:

  • Opening the DB

  • Closing the DB

  • Exception safety


Dependency Injection for Authentication

Auth dependency

def get_current_user(token: str = Depends(oauth2_scheme)): return decode_jwt(token)

Protected API

@app.get("/profile") def profile(user = Depends(get_current_user)): return user

✔ Auth logic is reusable
✔ APIs stay clean


Dependency Injection for Services (Spring Boot Style)

Service class

class UserService: def get_users(self): return ["Alice", "Bob"]

Dependency provider

def get_user_service(): return UserService()

API using service

@app.get("/users") def users(service: UserService = Depends(get_user_service)): return service.get_users()

📌 This is similar to:

@Autowired UserService userService;

Dependency Injection with Parameters

Dependencies can also accept parameters:

def common_params(limit: int = 10, offset: int = 0): return {"limit": limit, "offset": offset} @app.get("/items") def get_items(params = Depends(common_params)): return params

Great for:

  • Pagination

  • Filters

  • Query parameters


Nested Dependencies

Dependencies can depend on other dependencies:

def get_db(): ... def get_user(db = Depends(get_db)): ...

FastAPI resolves them automatically.


Dependency Injection for Testing (Huge Benefit)

Override dependency in tests

app.dependency_overrides[get_db] = get_test_db

✔ No real DB
✔ Faster tests
✔ Cleaner test setup


Common Use Cases for Dependency Injection in FastAPI

✅ Database sessions
✅ Authentication & authorization
✅ API keys
✅ Logging
✅ Configuration
✅ Feature flags


Common Mistakes to Avoid

❌ Creating DB connections inside endpoints
❌ Writing auth logic repeatedly
❌ Mixing business logic in controllers
❌ Not using DI for shared logic


FastAPI DI vs Spring Boot DI

FeatureFastAPISpring Boot
DI StyleFunction-basedAnnotation-based
Learning curveEasyMedium
FlexibilityVery highStructured
BoilerplateLowHigh

FastAPI DI is lighter, while Spring DI is more structured.


Best Practices

✔ Keep dependencies small
✔ Use DI for cross-cutting concerns
✔ Avoid heavy logic in endpoints
✔ Use DI for better testing
✔ Name dependencies clearly


Final Thoughts

FastAPI’s Dependency Injection system is:

  • Simple

  • Powerful

  • Pythonic

  • Production-ready

Once you master Depends(), your FastAPI code becomes:

  • Cleaner

  • More maintainable

  • Easier to scale


Suggested Next Reads

  • FastAPI Project Structure Best Practices

  • FastAPI Microservices Setup

  • FastAPI Authentication with JWT

  • FastAPI Interview Questions

FastAPI vs Flask vs Django: Which One Should You Choose?

In 2025, choosing the right Python web framework can make or break your backend development workflow. FastAPI, Flask, and Django are the most popular options—but which one is right for you? In this post, we’ll compare them based on performance, ease of use, scalability, and use cases.


What is FastAPI?

FastAPI is a modern Python framework designed for building high-performance APIs. It uses:

  • Python type hints for automatic request validation

  • Pydantic for data parsing and validation

  • ASGI for asynchronous support

Key Features:

  • Lightning-fast performance

  • Automatic Swagger and ReDoc documentation

  • Built-in validation and type safety

  • Async support for high-concurrency APIs

Best Use Cases: Microservices, API gateways, ML/AI APIs, integrations.


What is Flask?

Flask is a lightweight Python web framework that gives you full control over your application structure. It is often called a “micro-framework” because it provides the basics only, letting you add libraries as needed.

Key Features:

  • Minimal and flexible

  • Easy to learn for beginners

  • Large community and mature ecosystem

  • Supports extensions for database, authentication, and more

Best Use Cases: Small projects, prototypes, single-page applications, and microservices with simple APIs.


What is Django?

Django is a full-featured Python web framework that follows the “batteries-included” philosophy. It’s designed for building complex, large-scale web applications.

Key Features:

  • ORM for database management

  • Built-in authentication and admin interface

  • Strong security features

  • Scalable and maintainable

Best Use Cases: E-commerce, social media platforms, enterprise applications, content management systems.


FastAPI vs Flask vs Django: Detailed Comparison

FeatureFastAPIFlaskDjango
Performance⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Learning CurveEasyEasyMedium-High
Async Support✅ Native⚠️ (channels)
Automatic Docs✅ Swagger / ReDoc
Validation✅ Pydantic
Project SizeSmall to MediumSmallMedium to Large
CommunityGrowingLargeVery Large
Ideal ForAPIs, Microservices, MLPrototypes, MicroservicesEnterprise Apps, Full Web Apps

When to Choose FastAPI

✅ You want high-performance APIs
✅ You are building microservices
✅ Your project needs automatic validation and docs
✅ You are using Python async features
✅ You want fast development with minimal boilerplate


When to Choose Flask

✅ You want a flexible, lightweight framework
✅ You are building small apps or prototypes
✅ You want full control over libraries
✅ You are okay writing manual validation


When to Choose Django

✅ You need a full-stack solution
✅ You want built-in admin and auth
✅ You are building complex applications
✅ You want scalable and maintainable code


FastAPI vs Flask vs Django: Use Case Summary

  • FastAPI: Best for APIs, microservices, AI/ML endpoints

  • Flask: Best for small projects, prototypes, MVPs

  • Django: Best for large, full-featured web applications


Final Thoughts

Choosing the right framework depends on:

  1. Project type: API vs full web app

  2. Performance needs: High concurrency vs simple apps

  3. Team expertise: Python async knowledge vs classic web development

  4. Maintenance and scalability

Pro tip: Many companies use FastAPI for APIs and Django for the main web application, combining speed and full-featured power.

FastAPI Microservices Setup

 Below is a real-world FastAPI microservices setup, explained step by step, and mapped to how companies actually do it in production. I’ll also relate it to Spring Boot microservices, so it’s easy to grasp.


FastAPI Microservices Setup (Production-Ready Guide)

1️⃣ What Is a FastAPI Microservices Architecture?

Instead of one large backend, you create multiple small FastAPI services, each responsible for one business capability.

Example services:

  • Auth Service

  • User Service

  • Notification Service

  • Event / Integration Service

  • Reporting Service

Each service:

  • Has its own codebase

  • Has its own database (recommended)

  • Can be deployed and scaled independently


2️⃣ High-Level Architecture

Frontend (Angular / React / Mobile) ↓ API Gateway ↓ ┌────────┬─────────┬──────────┐ | Auth | Users | Events | FastAPI services |Service | Service | Service | └────────┴─────────┴──────────┘ ↓ Databases / Queues / Caches

3️⃣ Example Microservices Folder Structure

microservices/ │ ├── api-gateway/ │ └── app/ │ └── main.py │ ├── auth-service/ │ └── app/ │ ├── main.py │ └── api/ │ ├── user-service/ │ └── app/ │ ├── main.py │ └── api/ │ ├── event-service/ │ └── app/ │ ├── main.py │ └── api/ │ ├── docker-compose.yml └── README.md

👉 Each service is a separate FastAPI app.


4️⃣ Service-to-Service Communication

Option 1: REST (Most Common)

  • HTTP calls between services

  • Use async HTTP clients (httpx)

User Service → Auth Service

Option 2: Message Queue (Recommended for scale)

  • Kafka / RabbitMQ / AWS SQS

  • Event-driven communication

Event Service → Queue → Notification Service

5️⃣ API Gateway (Very Important)

Companies use:

  • Nginx

  • Kong

  • FastAPI Gateway

Responsibilities:

  • Routing

  • Authentication

  • Rate limiting

  • Logging

Simple FastAPI Gateway Example

@app.api_route("/{path:path}", methods=["GET", "POST"]) async def proxy(path: str, request: Request): async with httpx.AsyncClient() as client: response = await client.request( request.method, f"http://user-service/{path}", headers=request.headers.raw, content=await request.body() ) return Response(response.content)

6️⃣ Authentication Strategy

Central Auth Service (Recommended)

Flow:

  1. User logs in → Auth Service

  2. JWT token issued

  3. Other services validate JWT

Each service:

  • Validates token

  • Does not store auth logic

📌 Same idea as Spring Security + JWT.


7️⃣ Database Strategy

Best practice:

  • One database per service

Examples:

  • Auth Service → PostgreSQL

  • User Service → MongoDB

  • Event Service → NoSQL / Kafka

❌ Avoid shared databases between services.


8️⃣ Async & Performance Setup

Run services using:

Gunicorn + Uvicorn workers

Example:

gunicorn app.main:app -k uvicorn.workers.UvicornWorker -w 4

9️⃣ Docker Setup (Per Service)

Dockerfile (Common for all services)

FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY app app CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

🔟 docker-compose (Local Development)

version: "3.8" services: auth-service: build: ./auth-service ports: - "8001:8000" user-service: build: ./user-service ports: - "8002:8000" event-service: build: ./event-service ports: - "8003:8000"

1️⃣1️⃣ Configuration Management

Use:

  • .env files

  • Environment variables

  • Secrets manager (in prod)

Example:

AUTH_SERVICE_URL=http://auth-service:8000

1️⃣2️⃣ Logging & Monitoring

Production services include:

  • Structured logging

  • Request tracing (request ID)

  • Metrics (Prometheus)

  • Central log aggregation


1️⃣3️⃣ Scaling Strategy

  • Stateless services

  • Horizontal scaling

  • Kubernetes HPA

  • Load balancing via ingress


1️⃣4️⃣ FastAPI vs Spring Boot Microservices

AspectFastAPISpring Boot
Startup timeVery fastSlower
Resource usageLowHigher
AsyncSimpleComplex
Enterprise toolingModerateExcellent

Many companies use:

Spring Boot → Core services FastAPI → Integration & API services

1️⃣5️⃣ Common Mistakes to Avoid

❌ Sharing databases
❌ Tight coupling between services
❌ Missing API gateway
❌ Blocking calls in async routes
❌ No centralized auth


Final Thoughts

FastAPI microservices are:

  • Lightweight

  • Fast

  • Easy to scale

  • Perfect for integration-heavy systems

For someone with your background:

  • Spring Boot → Core business logic

  • FastAPI → Microservices, integrations, ML APIs

This combo is very powerful in modern architectures.

FastAPI Project Structure

 

Production Best Practices

1️⃣ Recommended Folder Structure

fastapi-app/ │ ├── app/ │ ├── main.py # Entry point (like SpringBootApplication) │ │ │ ├── core/ # Core configs (security, settings) │ │ ├── config.py # App settings (env based) │ │ ├── security.py # Auth, JWT, OAuth2 │ │ └── logging.py │ │ │ ├── api/ # API layer (Controllers) │ │ ├── v1/ │ │ │ ├── router.py # API router aggregation │ │ │ └── endpoints/ │ │ │ ├── users.py │ │ │ ├── auth.py │ │ │ └── health.py │ │ │ ├── models/ # DB models (Entities) │ │ ├── user.py │ │ └── base.py │ │ │ ├── schemas/ # Pydantic schemas (DTOs) │ │ ├── user.py │ │ └── auth.py │ │ │ ├── services/ # Business logic (Service layer) │ │ ├── user_service.py │ │ └── auth_service.py │ │ │ ├── repositories/ # DB access layer │ │ └── user_repo.py │ │ │ ├── db/ # Database setup │ │ ├── session.py │ │ └── init_db.py │ │ │ ├── middlewares/ # Custom middleware │ │ └── request_log.py │ │ │ ├── utils/ # Utilities/helpers │ │ └── date_utils.py │ │ │ └── tests/ # Unit & integration tests │ └── test_users.py │ ├── requirements.txt ├── Dockerfile ├── docker-compose.yml ├── .env └── README.md

2️⃣ Mapping to Spring Boot (So It Feels Familiar)

Spring BootFastAPI
@SpringBootApplicationmain.py
Controllerapi/endpoints
Serviceservices
Repositoryrepositories
Entitymodels
DTOschemas
application.ymlconfig.py / .env
Filtersmiddlewares

3️⃣ main.py – Application Entry Point

from fastapi import FastAPI from app.api.v1.router import api_router app = FastAPI(title="FastAPI App") app.include_router(api_router, prefix="/api/v1")

➡ Similar to:

@SpringBootApplication public class App { }

4️⃣ Router Aggregation (Like Controller Scanning)

api/v1/router.py

from fastapi import APIRouter from app.api.v1.endpoints import users, auth, health api_router = APIRouter() api_router.include_router(users.router, prefix="/users", tags=["Users"]) api_router.include_router(auth.router, prefix="/auth", tags=["Auth"]) api_router.include_router(health.router, prefix="/health", tags=["Health"])

5️⃣ Controller Layer (Endpoints)

api/v1/endpoints/users.py

from fastapi import APIRouter from app.schemas.user import UserCreate router = APIRouter() @router.post("/") def create_user(user: UserCreate): return {"message": "User created"}

6️⃣ Schema (DTO)

schemas/user.py

from pydantic import BaseModel class UserCreate(BaseModel): name: str email: str

7️⃣ Service Layer (Business Logic)

services/user_service.py

def create_user(user): # business rules here return user

8️⃣ Repository Layer (DB Access)

repositories/user_repo.py

def save(user): pass

9️⃣ Dependency Injection (FastAPI Style)

from fastapi import Depends def get_user_service(): return UserService() @router.get("/{id}") def get_user(id: int, service=Depends(get_user_service)): return service.find(id)

➡ Similar concept to @Autowired.


🔟 Environment Configuration

.env

DB_URL=mongodb://localhost:27017/app JWT_SECRET=secret

config.py

from pydantic import BaseSettings class Settings(BaseSettings): DB_URL: str JWT_SECRET: str settings = Settings()

1️⃣1️⃣ Testing Structure

tests/ ├── test_users.py └── conftest.py

Uses:

  • pytest

  • TestClient


1️⃣2️⃣ Production-Grade Tips

✅ Keep business logic out of controllers
✅ Use async DB drivers
✅ Version your APIs (/v1)
✅ Use dependency injection properly
✅ Add middleware for logging
✅ Use Docker for consistency


1️⃣3️⃣ Minimal Structure (For Small Services)

app/ ├── main.py ├── routes.py ├── schemas.py └── services.py

Use this only for small microservices.


Final Thoughts

FastAPI doesn’t force structure like Spring Boot, but teams must enforce discipline.

If you follow the above structure:

  • Code stays clean

  • Team collaboration improves

  • Scaling becomes easy

FastAPI Interview Questions and Answers (Beginner to Advanced)

FastAPI has quickly become one of the most popular Python frameworks for building high-performance APIs. As a result, FastAPI interview questions are now common in backend, microservices, and AI/ML roles.

This post covers commonly asked FastAPI interview questions with simple and clear answers, from basic concepts to advanced topics.


1️⃣ What is FastAPI?

FastAPI is a modern, high-performance Python web framework used to build REST APIs quickly.
It is built on Starlette for web handling and Pydantic for data validation.

Key features:

  • Fast performance

  • Automatic API documentation

  • Built-in request validation

  • Async support


2️⃣ Why is FastAPI faster than Flask or Django?

FastAPI is faster because:

  • It uses ASGI instead of WSGI

  • Supports async/await

  • Uses Uvicorn (high-performance server)

  • Minimizes blocking IO

This makes FastAPI ideal for high-concurrency APIs.


3️⃣ What is ASGI and how is it different from WSGI?

WSGIASGI
SynchronousAsynchronous
One request per threadEvent-loop based
Used by Flask, DjangoUsed by FastAPI

FastAPI uses ASGI, enabling better scalability.


4️⃣ What are Pydantic models?

Pydantic models are used for:

  • Request body validation

  • Response validation

  • Type enforcement

Example:

class User(BaseModel): name: str age: int

FastAPI automatically validates incoming JSON against this model.


5️⃣ How does FastAPI generate Swagger documentation?

FastAPI automatically generates OpenAPI (Swagger) documentation using:

  • Python type hints

  • Route definitions

  • Pydantic models

Available at:

  • /docs (Swagger UI)

  • /redoc (ReDoc)


6️⃣ What is dependency injection in FastAPI?

Dependency Injection (DI) allows reusable components like:

  • Database sessions

  • Authentication logic

  • Common validations

Example:

Depends(get_db)

It improves code reusability and testability.


7️⃣ How do you handle authentication in FastAPI?

FastAPI supports:

  • OAuth2

  • JWT

  • API Keys

  • Basic Auth

It provides built-in security utilities like:

OAuth2PasswordBearer

8️⃣ What is the difference between def and async def in FastAPI?

defasync def
BlockingNon-blocking
CPU-bound tasksIO-bound tasks
SimplerHigh concurrency

Use async def when calling:

  • Databases

  • External APIs

  • Message queues


9️⃣ How does FastAPI handle request validation errors?

FastAPI:

  • Automatically validates requests

  • Returns HTTP 422 (Unprocessable Entity)

  • Provides clear error messages

No manual validation code is required.


🔟 How do you connect FastAPI to a database?

FastAPI supports:

  • SQLAlchemy (SQL)

  • Motor (MongoDB)

  • Async ORMs

Typically:

  • Create a DB session dependency

  • Inject it using Depends()


1️⃣1️⃣ How do you write unit tests in FastAPI?

FastAPI uses:

  • pytest

  • TestClient

Example:

def test_health(): response = client.get("/health") assert response.status_code == 200

1️⃣2️⃣ How is FastAPI deployed in production?

Typical production setup:

Nginx ↓ Gunicorn + Uvicorn workers ↓ FastAPI app

Often containerized using Docker and orchestrated with Kubernetes.


1️⃣3️⃣ How does FastAPI compare to Spring Boot?

FastAPISpring Boot
PythonJava
Async-firstThread-based
Minimal configHeavy config
Fast developmentEnterprise stability

Many companies use both together.


1️⃣4️⃣ What are background tasks in FastAPI?

Background tasks allow execution after response is sent.

Used for:

  • Sending emails

  • Logging

  • Notifications

Example:

BackgroundTasks

1️⃣5️⃣ What are common FastAPI interview mistakes?

❌ Using def instead of async def
❌ Blocking calls inside async routes
❌ Ignoring dependency injection
❌ Not handling exceptions properly
❌ Poor project structure


Advanced FastAPI Interview Questions (For Experienced Devs)

  • How does FastAPI handle concurrency internally?

  • How do you implement rate limiting?

  • How do you use middleware in FastAPI?

  • How do you secure APIs using OAuth2 + JWT?

  • How do you scale FastAPI horizontally?

  • How do you integrate FastAPI with Kafka / RabbitMQ?


Final Thoughts

FastAPI is not just a framework, it’s a modern API philosophy:

  • Clean code

  • High performance

  • Strong typing

  • Developer-friendly