FastAPI Project Structure and Components
This document defines the recommended structure for a FastAPI backend.
It combines best practices from industry resources and the FastAPI official guide to ensure modularity, maintainability, and scalability.
1. Recommended Project Layout
fastapi_backend/
βββ app/
β βββ main.py
β βββ dependencies.py
β βββ core/
β β βββ config.py
β β βββ security.py
β βββ db/
β β βββ session.py
β β βββ base_class.py
β β βββ init_db.py
β βββ models/
β β βββ user.py
β β βββ item.py
β βββ schemas/
β β βββ user.py
β β βββ item.py
β βββ crud/
β β βββ user.py
β β βββ item.py
β βββ api/
β β βββ deps.py
β β βββ api_v1/
β β β βββ endpoints/
β β β β βββ users.py
β β β β βββ items.py
β β β βββ api.py
β βββ utils/
β βββ email.py
β βββ logging.py
βββ tests/
βββ .env
βββ requirements.txt
2. Layered Architecture Overview
| Layer | Purpose | Example Components |
|---|---|---|
| API (Presentation) | Handles routing, request validation, responses | /api/endpoints/*.py |
| Service / CRUD | Encapsulates business logic and DB operations | /crud/*.py |
| Data (Persistence) | Defines ORM models and schemas | /models/, /schemas/ |
| Core / Config | App config, startup events, security | /core/*.py |
| Infrastructure | Utilities, logging, third-party services | /utils/*.py |
3. Configuration and Dependency Management
Example: core/config.py
from pydantic import BaseSettings
class Settings(BaseSettings):
PROJECT_NAME: str = "FastAPI Backend"
DATABASE_URL: str
JWT_SECRET_KEY: str
API_V1_STR: str = "/api/v1"
class Config:
env_file = ".env"
settings = Settings()
Example: app/dependencies.py
from .db.session import SessionLocal
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
4. Router Organization
Each domain (users, items, etc.) has its own router file.
# app/api/api_v1/endpoints/users.py
from fastapi import APIRouter, Depends
from app import crud, schemas
from app.dependencies import get_db
router = APIRouter()
@router.get("/", response_model=list[schemas.User])
def list_users(db=Depends(get_db)):
return crud.user.get_all(db)
Routers are then included in api.py:
# app/api/api_v1/api.py
from fastapi import APIRouter
from .endpoints import users, items
api_router = APIRouter()
api_router.include_router(users.router, prefix="/users", tags=["Users"])
api_router.include_router(items.router, prefix="/items", tags=["Items"])
5. Database Layer
# app/db/session.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.core.config import settings
engine = create_engine(settings.DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
6. Real-Time Communication (WebSockets)
FastAPI natively supports WebSockets using Starlette under the hood.
A typical real-time setup includes a ConnectionManager class to handle active connections and broadcasts.
from fastapi import WebSocket
class ConnectionManager:
def __init__(self):
self.active_connections = []
async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)
async def broadcast(self, message: str):
for connection in self.active_connections:
await connection.send_text(message)
This can be extended to handle live collaboration, notifications, and status updates in your system.
7. Summary
A modular structure separates core logic from routing and data management.
This approach simplifies scaling, testing, and onboarding new developers β aligning with production-level best practices from the FastAPI ecosystem.