Description
Description
The current project uses a flat structure with separate folders for routes
, models
, schemas
, services
, and databases
. While this works fine for small applications, it doesn't scale well or follow FastAPI’s recommended "bigger applications" architecture.
This issue aims to migrate the project to a more idiomatic and maintainable structure as outlined in the FastAPI documentation.
Proposed Solution
Restructure the app to group logic by application layer inside an app/
package.
Each feature (e.g. players, health) will be scoped by file name inside their respective layer folders.
We’ll drop suffixes like _model
, _schema
, _service
, and _route
, since folder names already provide that context.
.
├── app
│ ├── __init__.py
│ ├── main.py
│ ├── dependencies.py
│ ├── routers
│ │ ├── __init__.py
│ │ ├── health.py
│ │ └── player.py
│ ├── models
│ │ ├── __init__.py
│ │ └── player.py
│ ├── schemas
│ │ ├── __init__.py
│ │ └── player.py
│ ├── services
│ │ ├── __init__.py
│ │ └── player.py
│ └── databases
│ ├── __init__.py
│ └── player.py
├── assets
│ └── images
├── compose.yaml
├── Dockerfile
├── requirements.txt
├── requirements-test.txt
├── requirements-lint.txt
├── runtime.txt
├── scripts
│ ├── entrypoint.sh
│ └── healthcheck.sh
├── storage
│ └── players-sqlite3.db
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── player_stub.py
│ └── test_main.py
├── postman_collections
├── README.md
├── LICENSE
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── codecov.yml
├── pyproject.toml
└── commitlint.config.mjs
This layout improves maintainability, import clarity, and readiness for scaling.
Suggested Approach
1. Create app/
package
- Create
app/
folder and add__init__.py
.
2. Move and simplify main.py
- Move
main.py
→app/main.py
. - Clean it up to just initialize the FastAPI instance and include routers.
- Update the router imports to reflect new paths and new router variable name:
- from routes import player_route, health_route
+ from app.routers import player, health
- And update the includes accordingly:
- app.include_router(player_route.api_router)
- app.include_router(health_route.api_router)
+ app.include_router(player.router)
+ app.include_router(health.router)
3. Rename and move route modules
- Move
routes/health_route.py
→app/routers/health.py
- Move
routes/player_route.py
→app/routers/player.py
- Update each file to define and export an
APIRouter
instance. - Update all import paths accordingly.
4. Move all logic layers under app/
and drop suffixes
- Move
models/player_model.py
→app/models/player.py
- Move
schemas/player_schema.py
→app/schemas/player.py
- Move
services/player_service.py
→app/services/player.py
- Move
databases/player_database.py
→app/databases/player.py
- Rename imports in all modules and tests.
5. (Optional) Add shared dependencies file
- Add
app/dependencies.py
for shared FastAPIDepends()
logic. - Not needed immediately, but useful for future expansion.
6. Update Docker/Compose
- Update
Dockerfile
andcompose.yaml
to run:
uvicorn app.main:app --host 0.0.0.0 --port 9000
7. Fix and verify tests
- Update all test imports to reflect new paths.
- Confirm all tests pass via
pytest
.
Acceptance Criteria
- All application logic resides under the
app/
package. - All
routes/
,models/
,schemas/
,services/
, anddatabases/
files are migrated toapp/
with renamed files (no suffixes). - All FastAPI routers are defined and imported correctly.
- Docker and
compose.yaml
use the updated app path. - All imports throughout the app and tests are updated.
- All existing tests pass after migration (
pytest
runs green). - Project structure matches FastAPI’s “bigger applications” guidance.