Hi, I’m Fast Eddy! As a backend web developer who spends most of my time with FastAPI, I’ve learned that maintainable, scalable project structure is the foundation of any robust API. Let’s break down how you can structure your FastAPI projects so they remain clear, scalable, and ready for growth—whether you’re working solo or leading a larger team.
Why Project Structure Matters
FastAPI makes it super easy to spin up endpoints fast. But as your project grows, you’ll quickly hit organizational hiccups if you stick with the default, single-file approach. Taking a bit of time to set up a thoughtful structure upfront can save countless headaches (and refactors) later.
Common Project Structure
Let’s look at a directory layout that works well for most mid- to large-sized projects:
myfastapiapp/
│
├── app/
│ ├── __init__.py
│ ├── main.py # Application entrypoint
│ ├── api/ # Routers and API logic
│ │ ├── __init__.py
│ │ └── v1/
│ │ ├── __init__.py
│ │ ├── endpoints/
│ │ │ ├── __init__.py
│ │ │ ├── users.py
│ │ │ └── items.py
│ │ └── dependencies.py
│ ├── core/ # Core app configs, settings, security, etc.
│ │ ├── __init__.py
│ │ ├── config.py
│ │ └── security.py
│ ├── models/ # Pydantic and ORM models
│ │ ├── __init__.py
│ │ ├── user.py
│ │ └── item.py
│ ├── crud/ # CRUD operations, DB logic
│ │ ├── __init__.py
│ │ ├── user.py
│ │ └── item.py
│ ├── db/ # Database session, metadata
│ │ ├── __init__.py
│ │ └── session.py
│ └── utils/ # Utility/helper functions
│ ├── __init__.py
│ └── email.py
├── tests/
│ ├── __init__.py
│ ├── test_users.py
│ └── test_items.py
├── alembic/ # Database migrations (if using Alembic)
├── .env
├── requirements.txt
├── Dockerfile
└── README.md
Key Principles
1. Separation of Concerns:
- Keep endpoints, business logic, and data models in their own modules.
- Avoid massive files that conglomerate unrelated logic.
2. API Versioning:
- Nest endpoints under
/api/v1/
(and so on) directories from the start. This simplifies future upgrades and backward compatibility.
3. Dependency Injection:
- Place shared dependencies (auth, DB sessions, etc.) in dedicated
dependencies.py
files.
4. Config Management:
- House settings and startup logic in
core/
for better organization and single sourcing of truth (read more in my previous article: "Managing Environment Variables in FastAPI Applications").
5. Utility Layer:
- Utilities or helpers go in a
utils/
folder to keep business logic clean.
Practical Example: Adding a User Endpoint
Suppose you want to add /users
endpoints. Here’s what you’d do:
- Create a
users.py
file under bothmodels/
andcrud/
for the schemas and CRUD functions. - Add endpoint logic to
api/v1/endpoints/users.py
. - Route all
/users
requests from your main router file (api/v1/__init__.py
). - Wire up dependencies in
api/v1/dependencies.py
as needed.
Scaling Up
This structure supports the addition of:
- More teams or developers (clear file boundaries help code reviews and onboarding)
- New API versions
- Plugins or third-party integrations
- Automated testing in the
tests/
directory
Summary
Properly structuring your FastAPI application sets you up for easier maintenance, painless scaling, and happier developers. A clear directory layout is the unsung hero of a project’s success.
Have your own best practices or run into structure headaches recently? Share your thoughts below or ping me on Dev Chat!
— Fast Eddy
Leave a Reply