FastAPI Modular Monolith Architecture — Project Scaffolder
Generate production-ready Modular Monolith projects with FastAPI, featuring proper module boundaries, async-first design, dependency injection, shared kernel, and infrastructure following industry best practices.
Overview
A Modular Monolith is a single deployable application organized into loosely coupled, highly cohesive modules — each representing a bounded context. FastAPI's speed, async capabilities, dependency injection system, and automatic API documentation make it an ideal framework for this architecture.
This skill scaffolds complete FastAPI projects with:
- Module isolation: Each module owns its models, repositories, services, routes, schemas, and dependencies
- Async-first design: All I/O operations use async/await (SQLAlchemy async, aiosmtplib, aiocache)
- FastAPI dependency injection: Loose coupling via
Depends() and Annotated types
- Generic repository pattern: Base CRUD with pagination, filtering, sorting, and soft deletes
- Inter-module communication: Via gateway contracts and domain events (fastapi-events)
- Shared kernel (core): Cross-cutting concerns — base models, config, services, exception handling
- Database-per-module schema: Logical isolation within a single PostgreSQL database via Alembic
- Production-ready: Docker, Redis caching, task queues (Taskiq), structured logging, rate limiting
- Migration-ready boundaries: Modules can be extracted to microservices later
Workflow
Step 1: Gather Requirements
If the user hasn't specified, ask for:
- Project name (e.g.,
conduit, saas-platform, ecommerce-api)
- Business modules (e.g., Auth, Articles, Comments, Payments, Notifications)
- Database preference (PostgreSQL recommended, MySQL supported)
- Additional features: Event bus, caching (Redis), task queue, email, Docker, CI/CD
- Authentication method: JWT (default), OAuth2, API keys
If the user provides $ARGUMENTS, parse them: $ARGUMENTS[0] = project name, remaining = module names.
Step 2: Generate Project Structure
Read the architecture references for FastAPI:
- For detailed project structure, see references/project-structure.md
- For module design patterns, see references/module-design.md
- For architecture decisions and comparisons, see references/architecture-guide.md
- For event-driven patterns, see references/event-driven-patterns.md
- For database patterns (SQLAlchemy async, Alembic), see references/database-patterns.md
- For testing strategies (pytest, TestClient), see references/testing-strategies.md
- For authentication and security patterns, see references/authentication-security.md
- For deployment and scaling, see references/deployment-scaling.md
- For a concrete Conduit (Medium clone) scaffold, see examples/conduit-scaffold.md
- For the generated README template, see examples/README-template.md
Generate the project following these critical rules:
Module Rules
- Each module gets its own directory with internal layers:
models/, schemas/, repositories/, services/, routes/, dependencies/
- Modules communicate ONLY through gateway contracts — never import another module's internal types
- Each module has its own Alembic migration files
- Each module registers its own dependencies via
Depends() functions
- No circular dependencies between modules
- Each module has its own
routers.py that aggregates its versioned route files
Shared Kernel (Core) Rules
- Contains ONLY cross-cutting concerns: base models, configuration, database session, generic repository, API response schemas, service interfaces (cache, mail, queue, log, events), exception handlers, middlewares
- Must be thin — if it grows large, something belongs in a module
- Never contains business logic specific to any module
Infrastructure Rules
- Single entry point:
app/main.py (FastAPI app initialization)
- Composition root:
app/core/routers.py wires all module routers together
- Database session is shared but models/schemas are isolated per module
- Domain events via
fastapi-events for async inter-module communication (upgradeable to Kafka/RabbitMQ)
- Background tasks via Taskiq with Redis backend
Step 3: Generate Code
For each module, generate:
- Models layer (
models/): SQLAlchemy ORM models with soft delete support
- Schemas layer (
schemas/): Pydantic v2 request/response/DTO schemas
- Repository layer (
repositories/): Data access extending BaseRepository with custom queries
- Service layer (
services/): Business logic with event dispatch and cross-cutting service calls
- Routes layer (
routes/v1/): Versioned API endpoints with FastAPI routers
- Dependencies layer (
dependencies/): DI setup for repositories, services, and auth guards
- Gateway (
gateway.py): Public interface exposing module functionality to other modules
- Events (
events.py): Domain event definitions
- Exceptions (
exceptions.py): Module-specific custom exceptions
- Config (
config.py): Module-specific configuration
Also generate:
- Shared kernel (
app/core/): Base classes, database setup, generic repository, API schemas, service interfaces, exception handlers, middlewares, dependency injection
- Entry point (
app/main.py): FastAPI app with lifespan, middleware registration, exception handlers
- Tests: Unit tests, integration tests, factories, and architecture boundary tests — see references/testing-strategies.md
- Docker (if requested): Dockerfile + docker-compose with PostgreSQL, Redis, Taskiq worker, and Mailhog — see references/deployment-scaling.md
- Alembic: Migration configuration with
alembic.ini and migrations/env.py
- pyproject.toml: Dependencies managed with UV or pip
- README.md: Architecture overview, how to run, how to add modules (use examples/README-template.md)
Step 4: Validate
After generation:
- Verify no module directly imports another module's internal types (only gateways)
- Confirm each module has its own models and migration support
- Check that the shared kernel (
app/core/) contains no business logic
- Ensure the project runs successfully with
uvicorn app.main:app --reload
- Run any generated tests with
pytest
Validation scripts are available in scripts/ for CI integration:
scripts/validate-boundaries.sh <app-dir> — detects cross-module boundary violations in Python imports
scripts/validate-shared-kernel.sh <core-dir> <modules-dir> — ensures core doesn't reference modules
scripts/check-circular-deps.sh <app-dir> — detects circular dependencies between modules
Step 5: Migration Guidance
If the user asks about extracting modules to microservices:
- Replace gateway contracts (in-process function calls) with HTTP/gRPC clients
- Swap
fastapi-events for Kafka/RabbitMQ for that module's events
- Migrate module's database tables to a separate database
- Deploy the extracted module as a standalone FastAPI service
- Keep remaining modules as a monolith (no need to extract everything)
Key Principles to Enforce
| Principle |
What It Means |
How to Enforce in FastAPI |
| High Cohesion |
Module contains everything for its domain |
models + schemas + repos + services + routes per module |
| Low Coupling |
Modules don't depend on each other's internals |
Communication only via gateway contracts |
| Dependency Injection |
All dependencies are explicit and injectable |
FastAPI Depends() with Annotated types |
| Async-First |
All I/O operations are non-blocking |
async def for routes, services, repositories |
| Repository Pattern |
Data access is abstracted behind interfaces |
BaseRepository[Model, Create, Update] generic class |
| Schema Separation |
Request/response/DTO schemas are distinct |
Pydantic v2 models in schemas/ per module |
| Event-Driven Communication |
Async inter-module messaging |
fastapi-events with domain event dispatch |
| Encapsulated Data |
Module owns its data |
Per-module SQLAlchemy models, no cross-module FKs |
Example Invocations
/modular-monolith-architecture-FastAPI conduit Auth Articles Comments
/modular-monolith-architecture-FastAPI ecommerce-api Auth Products Orders Payments
/modular-monolith-architecture-FastAPI saas-platform Auth Tenants Billing Notifications
/modular-monolith-architecture-FastAPI social-api Auth Users Posts Messages
When NOT to Use This
Suggest microservices instead if the user describes:
- Teams needing completely independent deployment cadences
- Requirements for polyglot tech stacks (Python ML + Go APIs + Java enterprise)
- Extreme per-service scaling requirements
- Already having Kubernetes infrastructure and DevOps maturity
Suggest a simple FastAPI monolith if:
- Solo developer or very small team (1-3 devs)
- Prototype/MVP with unclear domain boundaries
- Application with fewer than 3 distinct business domains
- Simple CRUD API without complex business logic
Technology Stack
| Category |
Technology |
Purpose |
| Framework |
FastAPI |
Web framework with async support |
| ORM |
SQLAlchemy 2.0 (async) |
Database ORM with async session |
| Validation |
Pydantic v2 |
Request/response validation and serialization |
| Database |
PostgreSQL |
Primary relational database |
| Cache |
Redis + aiocache |
Caching with async Redis backend |
| Migrations |
Alembic |
Database schema migrations |
| Auth |
PyJWT + Passlib (Argon2) |
JWT tokens + password hashing |
| Events |
fastapi-events |
In-process domain event dispatcher |
| Task Queue |
Taskiq + Redis |
Async background job processing |
| Email |
aiosmtplib + Jinja2 |
Async email with templates |
| Logging |
structlog |
Structured async logging |
| Testing |
pytest + httpx + faker + factory-boy |
Comprehensive test suite |
| Package Manager |
UV |
Fast Python dependency management |
| Linting |
Ruff |
Code linter and formatter |
| Type Checking |
MyPy |
Static type analysis |
| Containerization |
Docker + docker-compose |
Development and deployment |
1---2name: modular-monolith-architecture-fastapi3description: Scaffold and create a Modular Monolith Architecture project using Python/FastAPI. Use when the user wants to create a new FastAPI modular monolith, restructure a FastAPI monolith into modules, design module boundaries, or set up a FastAPI project following modular monolith best practices with async support, SQLAlchemy, and production-ready patterns.4---56# FastAPI Modular Monolith Architecture — Project Scaffolder78Generate production-ready Modular Monolith projects with FastAPI, featuring proper module boundaries, async-first design, dependency injection, shared kernel, and infrastructure following industry best practices.910## Overview1112A Modular Monolith is a single deployable application organized into loosely coupled, highly cohesive modules — each representing a bounded context. FastAPI's speed, async capabilities, dependency injection system, and automatic API documentation make it an ideal framework for this architecture.1314This skill scaffolds complete FastAPI projects with:15- **Module isolation**: Each module owns its models, repositories, services, routes, schemas, and dependencies16- **Async-first design**: All I/O operations use async/await (SQLAlchemy async, aiosmtplib, aiocache)17- **FastAPI dependency injection**: Loose coupling via `Depends()` and `Annotated` types18- **Generic repository pattern**: Base CRUD with pagination, filtering, sorting, and soft deletes19- **Inter-module communication**: Via gateway contracts and domain events (fastapi-events)20- **Shared kernel (core)**: Cross-cutting concerns — base models, config, services, exception handling21- **Database-per-module schema**: Logical isolation within a single PostgreSQL database via Alembic22- **Production-ready**: Docker, Redis caching, task queues (Taskiq), structured logging, rate limiting23- **Migration-ready boundaries**: Modules can be extracted to microservices later2425## Workflow2627### Step 1: Gather Requirements2829If the user hasn't specified, ask for:301. **Project name** (e.g., `conduit`, `saas-platform`, `ecommerce-api`)312. **Business modules** (e.g., Auth, Articles, Comments, Payments, Notifications)323. **Database** preference (PostgreSQL recommended, MySQL supported)334. **Additional features**: Event bus, caching (Redis), task queue, email, Docker, CI/CD345. **Authentication method**: JWT (default), OAuth2, API keys3536If the user provides `$ARGUMENTS`, parse them: `$ARGUMENTS[0]` = project name, remaining = module names.3738### Step 2: Generate Project Structure3940Read the architecture references for FastAPI:41- For detailed project structure, see [references/project-structure.md](references/project-structure.md)42- For module design patterns, see [references/module-design.md](references/module-design.md)43- For architecture decisions and comparisons, see [references/architecture-guide.md](references/architecture-guide.md)44- For event-driven patterns, see [references/event-driven-patterns.md](references/event-driven-patterns.md)45- For database patterns (SQLAlchemy async, Alembic), see [references/database-patterns.md](references/database-patterns.md)46- For testing strategies (pytest, TestClient), see [references/testing-strategies.md](references/testing-strategies.md)47- For authentication and security patterns, see [references/authentication-security.md](references/authentication-security.md)48- For deployment and scaling, see [references/deployment-scaling.md](references/deployment-scaling.md)49- For a concrete Conduit (Medium clone) scaffold, see [examples/conduit-scaffold.md](examples/conduit-scaffold.md)50- For the generated README template, see [examples/README-template.md](examples/README-template.md)5152Generate the project following these **critical rules**:5354#### Module Rules551. Each module gets its own directory with internal layers: `models/`, `schemas/`, `repositories/`, `services/`, `routes/`, `dependencies/`562. Modules communicate ONLY through gateway contracts — never import another module's internal types573. Each module has its own Alembic migration files584. Each module registers its own dependencies via `Depends()` functions595. No circular dependencies between modules606. Each module has its own `routers.py` that aggregates its versioned route files6162#### Shared Kernel (Core) Rules631. Contains ONLY cross-cutting concerns: base models, configuration, database session, generic repository, API response schemas, service interfaces (cache, mail, queue, log, events), exception handlers, middlewares642. Must be thin — if it grows large, something belongs in a module653. Never contains business logic specific to any module6667#### Infrastructure Rules681. Single entry point: `app/main.py` (FastAPI app initialization)692. Composition root: `app/core/routers.py` wires all module routers together703. Database session is shared but models/schemas are isolated per module714. Domain events via `fastapi-events` for async inter-module communication (upgradeable to Kafka/RabbitMQ)725. Background tasks via Taskiq with Redis backend7374### Step 3: Generate Code7576For each module, generate:77- **Models layer** (`models/`): SQLAlchemy ORM models with soft delete support78- **Schemas layer** (`schemas/`): Pydantic v2 request/response/DTO schemas79- **Repository layer** (`repositories/`): Data access extending `BaseRepository` with custom queries80- **Service layer** (`services/`): Business logic with event dispatch and cross-cutting service calls81- **Routes layer** (`routes/v1/`): Versioned API endpoints with FastAPI routers82- **Dependencies layer** (`dependencies/`): DI setup for repositories, services, and auth guards83- **Gateway** (`gateway.py`): Public interface exposing module functionality to other modules84- **Events** (`events.py`): Domain event definitions85- **Exceptions** (`exceptions.py`): Module-specific custom exceptions86- **Config** (`config.py`): Module-specific configuration8788Also generate:89- **Shared kernel** (`app/core/`): Base classes, database setup, generic repository, API schemas, service interfaces, exception handlers, middlewares, dependency injection90- **Entry point** (`app/main.py`): FastAPI app with lifespan, middleware registration, exception handlers91- **Tests**: Unit tests, integration tests, factories, and architecture boundary tests — see [references/testing-strategies.md](references/testing-strategies.md)92- **Docker** (if requested): Dockerfile + docker-compose with PostgreSQL, Redis, Taskiq worker, and Mailhog — see [references/deployment-scaling.md](references/deployment-scaling.md)93- **Alembic**: Migration configuration with `alembic.ini` and `migrations/env.py`94- **pyproject.toml**: Dependencies managed with UV or pip95- **README.md**: Architecture overview, how to run, how to add modules (use [examples/README-template.md](examples/README-template.md))9697### Step 4: Validate9899After generation:1001. Verify no module directly imports another module's internal types (only gateways)1012. Confirm each module has its own models and migration support1023. Check that the shared kernel (`app/core/`) contains no business logic1034. Ensure the project runs successfully with `uvicorn app.main:app --reload`1045. Run any generated tests with `pytest`105106Validation scripts are available in [scripts/](scripts/) for CI integration:107- `scripts/validate-boundaries.sh <app-dir>` — detects cross-module boundary violations in Python imports108- `scripts/validate-shared-kernel.sh <core-dir> <modules-dir>` — ensures core doesn't reference modules109- `scripts/check-circular-deps.sh <app-dir>` — detects circular dependencies between modules110111### Step 5: Migration Guidance112113If the user asks about extracting modules to microservices:114- Replace gateway contracts (in-process function calls) with HTTP/gRPC clients115- Swap `fastapi-events` for Kafka/RabbitMQ for that module's events116- Migrate module's database tables to a separate database117- Deploy the extracted module as a standalone FastAPI service118- Keep remaining modules as a monolith (no need to extract everything)119120## Key Principles to Enforce121122| Principle | What It Means | How to Enforce in FastAPI |123|-----------|---------------|--------------------------|124| High Cohesion | Module contains everything for its domain | models + schemas + repos + services + routes per module |125| Low Coupling | Modules don't depend on each other's internals | Communication only via gateway contracts |126| Dependency Injection | All dependencies are explicit and injectable | FastAPI `Depends()` with `Annotated` types |127| Async-First | All I/O operations are non-blocking | `async def` for routes, services, repositories |128| Repository Pattern | Data access is abstracted behind interfaces | `BaseRepository[Model, Create, Update]` generic class |129| Schema Separation | Request/response/DTO schemas are distinct | Pydantic v2 models in `schemas/` per module |130| Event-Driven Communication | Async inter-module messaging | `fastapi-events` with domain event dispatch |131| Encapsulated Data | Module owns its data | Per-module SQLAlchemy models, no cross-module FKs |132133## Example Invocations134135```136/modular-monolith-architecture-FastAPI conduit Auth Articles Comments137/modular-monolith-architecture-FastAPI ecommerce-api Auth Products Orders Payments138/modular-monolith-architecture-FastAPI saas-platform Auth Tenants Billing Notifications139/modular-monolith-architecture-FastAPI social-api Auth Users Posts Messages140```141142## When NOT to Use This143144Suggest microservices instead if the user describes:145- Teams needing completely independent deployment cadences146- Requirements for polyglot tech stacks (Python ML + Go APIs + Java enterprise)147- Extreme per-service scaling requirements148- Already having Kubernetes infrastructure and DevOps maturity149150Suggest a simple FastAPI monolith if:151- Solo developer or very small team (1-3 devs)152- Prototype/MVP with unclear domain boundaries153- Application with fewer than 3 distinct business domains154- Simple CRUD API without complex business logic155156## Technology Stack157158| Category | Technology | Purpose |159|----------|-----------|---------|160| Framework | FastAPI | Web framework with async support |161| ORM | SQLAlchemy 2.0 (async) | Database ORM with async session |162| Validation | Pydantic v2 | Request/response validation and serialization |163| Database | PostgreSQL | Primary relational database |164| Cache | Redis + aiocache | Caching with async Redis backend |165| Migrations | Alembic | Database schema migrations |166| Auth | PyJWT + Passlib (Argon2) | JWT tokens + password hashing |167| Events | fastapi-events | In-process domain event dispatcher |168| Task Queue | Taskiq + Redis | Async background job processing |169| Email | aiosmtplib + Jinja2 | Async email with templates |170| Logging | structlog | Structured async logging |171| Testing | pytest + httpx + faker + factory-boy | Comprehensive test suite |172| Package Manager | UV | Fast Python dependency management |173| Linting | Ruff | Code linter and formatter |174| Type Checking | MyPy | Static type analysis |175| Containerization | Docker + docker-compose | Development and deployment |