DEV Community

Zaenal Arifin
Zaenal Arifin

Posted on

🧩 How to Structure a FastAPI Project the Right Way

When you first start with FastAPI, it’s tempting to throw everything into a single file β€” and it works fine… until your app grows. Then suddenly, your codebase becomes spaghetti.

In this post, we’ll go through how to structure a FastAPI project properly, using clean architecture principles that scale easily.


πŸš€ Why Project Structure Matters

A good structure makes your project:

  • Easier to maintain and scale.
  • Easier for new developers to understand.
  • Ready for testing, CI/CD, and deployment.

If your FastAPI project looks like this:

main.py
models.py
routes.py
schemas.py
database.py
Enter fullscreen mode Exit fullscreen mode

…it’s time for an upgrade.


πŸ—οΈ Recommended Folder Structure

Here’s a clean, production-ready structure I use for real projects:

app/
β”œβ”€β”€ api/
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ users.py
β”‚   β”‚   β”œβ”€β”€ items.py
β”‚   β”‚   └── __init__.py
β”‚   β”œβ”€β”€ deps.py
β”‚   β”œβ”€β”€ __init__.py
β”‚   └── api_v1.py
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ config.py
β”‚   β”œβ”€β”€ security.py
β”‚   └── __init__.py
β”œβ”€β”€ db/
β”‚   β”œβ”€β”€ base.py
β”‚   β”œβ”€β”€ session.py
β”‚   └── __init__.py
β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ user.py
β”‚   β”œβ”€β”€ item.py
β”‚   └── __init__.py
β”œβ”€β”€ schemas/
β”‚   β”œβ”€β”€ user.py
β”‚   β”œβ”€β”€ item.py
β”‚   └── __init__.py
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ user_service.py
β”‚   └── __init__.py
β”œβ”€β”€ main.py
└── __init__.py
Enter fullscreen mode Exit fullscreen mode

βš™οΈ Let’s Break It Down

core/

Contains global configurations β€” environment variables, security settings, and constants.

# app/core/config.py
from pydantic import BaseSettings

class Settings(BaseSettings):
    APP_NAME: str = "My FastAPI App"
    DATABASE_URL: str

    class Config:
        env_file = ".env"

settings = Settings()
Enter fullscreen mode Exit fullscreen mode

db/

Handles all database setup β€” connection, session management, and base models.

# 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(bind=engine, autocommit=False, autoflush=False)
Enter fullscreen mode Exit fullscreen mode

api/routes/

Organize endpoints by domain β€” one file per feature.

# app/api/routes/users.py
from fastapi import APIRouter, Depends
from app.schemas.user import User
from app.services.user_service import get_all_users

router = APIRouter(prefix="/users", tags=["users"])

@router.get("/", response_model=list[User])
async def list_users():
    return await get_all_users()
Enter fullscreen mode Exit fullscreen mode

services/

Business logic lives here β€” keep it separate from routes.

# app/services/user_service.py
from app.db.session import SessionLocal
from app.models.user import User

async def get_all_users():
    db = SessionLocal()
    return db.query(User).all()
Enter fullscreen mode Exit fullscreen mode

main.py

The entry point that ties everything together.

# app/main.py
from fastapi import FastAPI
from app.api.api_v1 import api_router
from app.core.config import settings

app = FastAPI(title=settings.APP_NAME)
app.include_router(api_router)
Enter fullscreen mode Exit fullscreen mode

🧠 Tips for Scalable FastAPI Projects

βœ… Use Pydantic models for input/output validation
βœ… Split logic into layers β€” routes, services, models
βœ… Use dependency injection for clean imports
βœ… Add logging early β€” don’t debug with print()
βœ… Separate environment variables from code


🧰 Example Repository

I’ve uploaded an example of this structure here:
πŸ‘‰ GitHub - fastapi-clean-structure (insert your repo link)

You can clone it, install dependencies, and start your app in seconds:

git clone https://github.com/yourusername/fastapi-clean-structure.git
cd fastapi-clean-structure
poetry install
poetry run uvicorn app.main:app --reload
Enter fullscreen mode Exit fullscreen mode

πŸ”š Conclusion

Clean project structure isn’t just about being β€œorganized” β€” it’s about future-proofing your codebase.
FastAPI makes things fast, but structure makes them sustainable.

If you found this useful, drop a ❀️ or follow me β€” I post about Python, FastAPI, and backend architecture regularly.

Top comments (0)