Enforce FastAPI Clean Architecture with BLOCKING validation.
Architecture Overview
+-------------------------------------------------------------------+ | ROUTERS LAYER | | HTTP concerns only: request parsing, response formatting | | Files: router_.py, routes_.py, api_*.py | +-------------------------------------------------------------------+ | SERVICES LAYER | | Business logic: orchestration, validation, transformations | | Files: *_service.py | +-------------------------------------------------------------------+ | REPOSITORIES LAYER | | Data access: database queries, external API calls | | Files: *_repository.py, *_repo.py | +-------------------------------------------------------------------+ | MODELS LAYER | | Data structures: SQLAlchemy models, Pydantic schemas | | Files: *_model.py (ORM), *_schema.py (Pydantic) | +-------------------------------------------------------------------+
Validation Rules (BLOCKING)
Rule Check Layer
No DB in Routers Database operations blocked routers/
No HTTP in Services HTTPException blocked services/
No Business Logic in Routers Complex logic blocked routers/
Use Depends() Direct instantiation blocked routers/
Async Consistency Sync calls in async blocked all
File Naming Must follow naming convention all
File Naming Conventions
Quick Reference
Layer Allowed Patterns Blocked Patterns
Routers router_.py , routes_.py , api_*.py , deps.py
users.py , UserRouter.py
Services *_service.py
users.py , UserService.py , service_*.py
Repositories *_repository.py , *_repo.py
users.py , repository_*.py
Schemas *_schema.py , *_dto.py , *_request.py , *_response.py
users.py , UserSchema.py
Models *_model.py , *_entity.py , *_orm.py , base.py
users.py , UserModel.py
Layer Separation Summary
Routers (HTTP Only)
-
Request parsing and response formatting
-
HTTP status codes and auth checks
-
Delegate to services via Depends()
Services (Business Logic)
-
Validation and orchestration
-
Data transformations
-
Raise domain exceptions (NOT HTTPException)
Repositories (Data Access)
-
Database queries and persistence
-
External API calls
-
Return domain objects or None
Dependency Injection Quick Reference
deps.py - Dependency providers
def get_user_repository( db: AsyncSession = Depends(get_db), ) -> UserRepository: return UserRepository(db)
def get_user_service( repo: UserRepository = Depends(get_user_repository), ) -> UserService: return UserService(repo)
router_users.py - Usage
@router.get("/{user_id}") async def get_user( user_id: int, service: UserService = Depends(get_user_service), ): return await service.get_user(user_id)
Blocked DI Patterns
BLOCKED - Direct instantiation
service = UserService()
BLOCKED - Global instance
user_service = UserService()
BLOCKED - Missing Depends()
async def get_users(db: AsyncSession): # Missing Depends()
Common Violations
Violation Detection Fix
DB in router db.add , db.execute in routers/ Move to repository
HTTPException in service raise HTTPException in services/ Use domain exceptions
Direct instantiation Service() without Depends Use Depends(get_service)
Wrong naming Missing suffix/prefix Rename per convention
Sync in async Missing await
Add await or use executor
Exception Pattern
Domain exceptions (services/repositories)
class UserNotFoundError(DomainException): def init(self, user_id: int): super().init(f"User {user_id} not found")
Router converts to HTTP
@router.get("/{user_id}") async def get_user(user_id: int, service: UserService = Depends(get_user_service)): try: return await service.get_user(user_id) except UserNotFoundError: raise HTTPException(404, "User not found")
Async Rules
GOOD - Async all the way
result = await db.execute(select(User))
BLOCKED - Sync in async function
result = db.execute(select(User)) # Missing await
For sync code, use executor
await loop.run_in_executor(None, sync_function)
References
For detailed patterns and examples, see:
Reference Content
layer-rules.md Detailed layer separation rules with code examples
dependency-injection.md DI patterns, authentication, testing with overrides
violation-examples.md Common violations with proper patterns and auto-fix suggestions
Related Skills
-
clean-architecture
-
DDD patterns
-
fastapi-advanced
-
Advanced FastAPI patterns
-
dependency-injection
-
DI patterns
-
project-structure-enforcer
-
Folder structure
Capability Details
layer-separation
Keywords: router, service, repository, layer, clean architecture, separation Solves:
-
Prevent database operations in routers
-
Block business logic in route handlers
-
Ensure proper layer boundaries
dependency-injection
Keywords: depends, dependency injection, DI, fastapi depends, inject Solves:
-
Enforce use of FastAPI Depends() pattern
-
Block direct instantiation in routers
-
Ensure testable code structure
file-naming
Keywords: naming convention, file name, router_, _service, _repository Solves:
-
Enforce consistent file naming patterns
-
Validate router/service/repository naming
-
Maintain codebase consistency
async-patterns
Keywords: async, await, sync, blocking call, asyncio Solves:
-
Detect sync calls in async functions
-
Prevent blocking operations in async code
-
Ensure async consistency