Skip to content

darkspock/ddd_python_sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DDD Python Sample - Restaurant Booking System

A complete Domain-Driven Design implementation in Python, converted from Laravel.

Architecture

This project follows DDD patterns with a clear separation of concerns:

ddd_python_sample/
├── src/                              # Domain and Application layers
│   ├── shared/                       # Shared kernel
│   │   ├── domain/                   # Base classes (Entity, Event)
│   │   ├── application/              # Bus interfaces
│   │   └── infrastructure/           # Event bus, database session
│   ├── client_bc/                    # Client Bounded Context
│   │   └── client/
│   │       ├── domain/               # Entity, ValueObjects, Events
│   │       ├── application/          # Commands, Queries, DTOs
│   │       └── infrastructure/       # Repository, Model
│   └── reservation_bc/               # Reservation Bounded Context
│       └── booking/
│           ├── domain/               # Aggregate, ValueObjects, Events
│           ├── application/          # Commands, Queries, DTOs
│           └── infrastructure/       # Repository, Models
├── adapters/                         # Infrastructure adapters
│   └── http/                         # HTTP adapter (FastAPI)
│       └── api/
│           ├── clients/              # Client endpoints
│           └── bookings/             # Booking endpoints
├── tests/                            # Test suite
├── main.py                           # Application entry point
└── pyproject.toml                    # Python dependencies

DDD Patterns Implemented

Value Objects

  • Immutable (@dataclass(frozen=True))
  • Self-validating in __post_init__
  • ULID-based identifiers (26 characters)
  • Examples: BookingId, PartySize, Money, TimeSlot

Entities

  • Mutable (@dataclass)
  • Factory methods: create() and reconstitute()
  • Business logic encapsulated in methods
  • Domain events recorded on state changes

Aggregates

  • Booking is the aggregate root
  • Controls access to BookingProduct (child entity)
  • Enforces consistency boundaries

Domain Events

  • Immutable (@dataclass(frozen=True))
  • Past tense naming (BookingConfirmed, not ConfirmBooking)
  • Created via from_entity() factory methods
  • Published after successful persistence

Repository Pattern

  • Interface in domain layer (ABC)
  • Implementation in infrastructure layer (SQLAlchemy)
  • Mapper methods: _to_entity(), _to_model()

CQRS

  • Commands modify state
  • Queries return DTOs
  • Separate handlers for each

Bounded Contexts

Client BC

  • Client entity with ClientId
  • Events: ClientCreatedEvent
  • Commands: CreateClientCommand
  • Queries: GetClientByIdQuery

Reservation BC

  • Booking aggregate with BookingProduct
  • Value Objects: BookingId, PartySize, Money, TimeSlot
  • Enums: BookingStatus, ProductType
  • Events: BookingCreated, BookingConfirmed, BookingCancelled, etc.
  • Commands: CreateBooking, ConfirmBooking, CancelBooking
  • Queries: GetBookingById, IndexBookings

Running the Application

# Install dependencies
pip install poetry
poetry install

# Run the application
poetry run python main.py

# Or with uvicorn directly
poetry run uvicorn main:app --reload

API documentation available at: http://localhost:8000/docs

API Endpoints

Clients

  • POST /api/clients - Create client
  • GET /api/clients/{id} - Get client

Bookings

  • POST /api/bookings - Create booking
  • GET /api/bookings - List bookings (with filters)
  • GET /api/bookings/{id} - Get booking
  • POST /api/bookings/{id}/confirm - Confirm booking
  • POST /api/bookings/{id}/cancel - Cancel booking
  • GET /api/bookings/restaurant/{id} - Get bookings by restaurant

Testing

poetry run pytest

Key Design Decisions

  1. Value Objects as dataclass(frozen=True) - Ensures immutability
  2. ULID for IDs - Time-ordered, globally unique, URL-safe
  3. Factory methods on entities - create() for new, reconstitute() for hydration
  4. Events recorded in entity - Released after persistence
  5. DTOs for layer boundaries - Separate from domain objects
  6. Pydantic for HTTP schemas - Validation and serialization

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages