Clean Architecture & Framework-Agnostic Design
Decouple your core business logic from web frameworks and databases. Learn how data flows from HTTP routers to domain entities and abstract repositories.
The 4 Concentric Layers of Clean Architecture
The central directive: Business rules must not depend heavily on frameworks or databases.
FastAPI / Flask routers & controllers. Converts HTTP requests into application commands and formats HTTP JSON responses.
Single-responsibility workflows (`CreateOrderUseCase`). Orchestrates domain entities and calls repository interfaces.
Pure dataclasses & domain entities (`Order`, `OrderItem`). Pure calculation and validation logic with zero external imports.
PostgreSQL, SQLAlchemy, Redis, Message Queues (Celery/RabbitMQ), and external payment API clients (Stripe).
⚡ End-to-End Request Execution Flow
Notice how the Repository Interface acts as the inversion boundary. The application depends on abstract methods, while PostgreSQL provides the concrete implementation.
💻 Production Code Blueprint: Order Processing
Review how domain entities, abstract contracts, application use cases, and concrete adapters interact in Python.
# ─── 1. PURE DOMAIN ENTITY & ABSTRACT REPOSITORY CONTRACT ─────────────────
from dataclasses import dataclass
from abc import ABC, abstractmethod
@dataclass
class Order:
id: str | None
user_id: str
total_amount: float
class OrderRepository(ABC):
@abstractmethod
def save(self, order: Order) -> Order:
...
# ─── 2. APPLICATION USE CASE ───────────────────────────────────────────────
class CreateOrderUseCase:
def __init__(self, repository: OrderRepository) -> None:
self.repository = repository
def execute(self, user_id: str, amount: float) -> Order:
order = Order(id=None, user_id=user_id, total_amount=amount)
return self.repository.save(order)
# ─── 3. INFRASTRUCTURE POSTGRESQL ADAPTER ─────────────────────────────────
class PostgresOrderRepository(OrderRepository):
def save(self, order: Order) -> Order:
# SQL INSERT into postgres DB
order.id = "ord_9988"
return order
# ─── 4. API DELIVERY ROUTER (FASTAPI / FLASK) ──────────────────────────────
@router.post("/orders")
def create_order_endpoint(payload: dict, db=Depends(get_db)):
repo = PostgresOrderRepository(db)
use_case = CreateOrderUseCase(repo)
return use_case.execute(payload["user_id"], payload["amount"])