{"id":29196673,"url":"https://github.com/hpalma/ddd-verticalslice-example","last_synced_at":"2025-07-02T06:08:51.713Z","repository":{"id":301545617,"uuid":"1009594206","full_name":"hpalma/ddd-verticalslice-example","owner":"hpalma","description":"DDD implementation showcasing bounded contexts, CQRS pattern, domain events, and vertical slice architecture in Spring Boot.","archived":false,"fork":false,"pushed_at":"2025-06-27T11:45:06.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-27T12:37:02.253Z","etag":null,"topics":["ddd","ddd-example","java","vertical-slice-architecture"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hpalma.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-27T11:40:14.000Z","updated_at":"2025-06-27T11:52:22.000Z","dependencies_parsed_at":"2025-06-27T12:48:57.590Z","dependency_job_id":null,"html_url":"https://github.com/hpalma/ddd-verticalslice-example","commit_stats":null,"previous_names":["hpalma/ddd-verticalslice-example"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hpalma/ddd-verticalslice-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpalma%2Fddd-verticalslice-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpalma%2Fddd-verticalslice-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpalma%2Fddd-verticalslice-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpalma%2Fddd-verticalslice-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hpalma","download_url":"https://codeload.github.com/hpalma/ddd-verticalslice-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpalma%2Fddd-verticalslice-example/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263083735,"owners_count":23411166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ddd","ddd-example","java","vertical-slice-architecture"],"created_at":"2025-07-02T06:08:50.757Z","updated_at":"2025-07-02T06:08:51.704Z","avatar_url":"https://github.com/hpalma.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DDD Vertical Slice Architecture Demo with CQRS\n\nThis Spring Boot application demonstrates Domain-Driven Design (DDD) concepts implemented with a vertical slice architecture, featuring CQRS pattern, MapStruct mapping, and event-driven communication.\n\n## Architecture Overview\n\n### DDD Concepts Implemented\n\n1. **Entities** - Objects with identity (Order, Product, OrderItem, BankAccount, Transaction)\n2. **Value Objects** - Immutable objects without identity (OrderId, ProductId, Money, Price, AccountId, TransactionId)\n3. **Aggregate Roots** - Consistency boundaries with business rule validation (Order, Product, BankAccount)\n4. **Domain Events** - Events that occur within the domain (OrderCreated, AccountOpened, DepositMade, etc.)\n5. **Integration Events** - Cross-bounded-context communication (OrderPlacedIntegrationEvent)\n6. **Repositories** - Domain interface for data access\n7. **Domain Services** - Business logic that doesn't belong to a single entity\n8. **Bounded Contexts** - Clear boundaries between subdomains (Orders, Products, Banking)\n\n### CQRS Pattern\n\nThe application implements Command Query Responsibility Segregation (CQRS) with:\n- **Command Side**: Optimized for write operations, business logic execution, and consistency\n- **Query Side**: Optimized for read operations, projections, and analytics\n- **Shared Infrastructure**: Same datastore for both sides with different access patterns\n\n### Event-Driven Architecture\n\n- **Spring ApplicationEventPublisher**: For publishing domain and integration events\n- **Cross-Context Communication**: Products slice automatically reduces stock when orders are placed\n- **Event Handlers**: Asynchronous processing of domain events\n\n### Object Mapping with MapStruct\n\n- **Compile-time mapping**: Between domain objects and JPA entities\n- **Type-safe conversions**: Automatic generation of mapping code\n- **Custom mappings**: For complex value object transformations\n\n## Project Structure\n\n```\nsrc/main/java/com/example/\n├── shared/                    # Shared infrastructure and contracts\n│   ├── domain/               # Base DDD building blocks\n│   │   ├── Entity.java\n│   │   ├── ValueObject.java\n│   │   ├── AggregateRoot.java\n│   │   ├── DomainEvent.java\n│   │   └── DomainEventPublisher.java\n│   └── integration/          # Cross-context integration events\n│       └── OrderPlacedIntegrationEvent.java\n├── orders/                   # Order management bounded context\n│   ├── write/               # Command side (CQRS)\n│   │   ├── api/            # Command controllers and DTOs\n│   │   └── application/    # Command services and handlers\n│   ├── read/                # Query side (CQRS)\n│   │   ├── api/            # Query controllers\n│   │   ├── application/    # Query services and view repositories\n│   │   ├── infrastructure/ # Read-optimized data access\n│   │   └── query/          # Read models and projections\n│   └── shared/              # Shared between read/write sides\n│       ├── domain/         # Order domain model and events\n│       └── infrastructure/ # JPA entities, repositories, MapStruct mappers\n├── products/                # Product catalog bounded context\n│   ├── api/                # REST endpoints and DTOs\n│   ├── application/        # Use cases and event handlers\n│   ├── domain/             # Product domain model\n│   └── infrastructure/     # Data persistence and MapStruct mappers\n└── banking/                 # Banking bounded context (example)\n    ├── application/        # Banking services and event handlers\n    ├── domain/             # Account and transaction domain\n    └── infrastructure/     # Banking data persistence\n```\n\n## Key Features\n\n### 1. CQRS Implementation\n- **Write Operations**: Handled by command services optimized for consistency and business logic\n- **Read Operations**: Handled by query services with optimized projections and analytics\n- **Separate Controllers**: OrderCommandController and OrderQueryController\n- **Read Models**: OrderView, OrderSummaryView for optimized queries\n\n### 2. Cross-Context Communication\n- **Event-Driven Stock Management**: When orders are created, product stock is automatically reduced\n- **Integration Events**: Proper bounded context boundaries with shared contracts\n- **Error Handling**: Insufficient stock scenarios with compensating actions\n\n### 3. MapStruct Object Mapping\n- **Automatic Mapping**: Between Order ↔ OrderEntity, Product ↔ ProductEntity\n- **Value Object Conversion**: Custom mappers for complex types like TransactionId, Money\n- **Compile-time Safety**: No runtime reflection overhead\n\n### 4. Domain Event System\n- **Internal Events**: OrderCreated for within-context processing\n- **Integration Events**: OrderPlacedIntegrationEvent for cross-context communication\n- **Spring Events**: Leverages Spring's ApplicationEventPublisher infrastructure\n\n### 5. Banking Example (Aggregate Root Showcase)\n- **Business Rule Validation**: Daily withdrawal limits, account status checks\n- **Version Control**: Optimistic locking for concurrent access\n- **Complex Domain Logic**: Multiple transaction types with balance management\n\n## Running the Application\n\n### Prerequisites\n- Java 17+ (tested with Java 24)\n- Maven 3.9+ (Maven wrapper included)\n\n### Build and Run\n```bash\n# Using Maven wrapper (recommended)\n./mvnw spring-boot:run\n\n# Or with system Maven\nmvn spring-boot:run\n```\n\nThe application will start on port 8080.\n\n### Running Tests\n```bash\n# Run all tests\n./mvnw test\n\n# Run specific test\n./mvnw test -Dtest=OrderCommandServiceTest\n```\n\nNote: Tests are configured to work with Java 24 using experimental Byte Buddy support.\n\n## API Endpoints\n\n### Products\n- `POST /api/products` - Create a new product\n- `GET /api/products` - Get all products  \n- `GET /api/products/{id}` - Get product by ID\n- `GET /api/products/active` - Get active products only\n- `PUT /api/products/{id}/price` - Update product price\n- `PUT /api/products/{id}/stock` - Update product stock\n- `POST /api/products/{id}/deactivate` - Deactivate product\n\n### Orders - Command Side (Write Operations)\n- `POST /api/orders/commands` - Create a new order\n- `POST /api/orders/commands/{id}/confirm` - Confirm order\n- `POST /api/orders/commands/{id}/cancel` - Cancel order\n\n### Orders - Query Side (Read Operations)  \n- `GET /api/orders/queries` - Get all orders\n- `GET /api/orders/queries/{id}` - Get order by ID\n- `GET /api/orders/queries/customer/{customerId}` - Get orders by customer\n- `GET /api/orders/queries/status/{status}` - Get orders by status\n- `GET /api/orders/queries/recent?limit=10` - Get recent orders\n- `GET /api/orders/queries/analytics/{customerId}` - Get customer analytics\n\n## Example Usage\n\n### 1. Create a Product\n```json\nPOST /api/products\n{\n  \"name\": \"Laptop\",\n  \"description\": \"High-performance laptop\", \n  \"price\": 999.99,\n  \"stockQuantity\": 10\n}\n```\n\n### 2. Create an Order (CQRS Command)\n```json\nPOST /api/orders/commands\n{\n  \"customerId\": \"customer-123\",\n  \"items\": [\n    {\n      \"productId\": \"product-id\",\n      \"productName\": \"Laptop\",\n      \"unitPrice\": 999.99,\n      \"quantity\": 2\n    }\n  ]\n}\n```\n\n### 3. Query Orders (CQRS Query)\n```bash\n# Get customer analytics\nGET /api/orders/queries/analytics/customer-123\n\n# Get recent orders\nGET /api/orders/queries/recent?limit=5\n\n# Get orders by status\nGET /api/orders/queries/status/PENDING\n```\n\n## Event Flow Example\n\nWhen an order is created:\n\n1. **OrderCommandService** creates Order aggregate\n2. **OrderCreated** domain event is published (internal to orders context)\n3. **OrderPlacedIntegrationEvent** is published (cross-context)\n4. **ProductOrderEventHandler** catches integration event\n5. **ProductStockService** reduces stock for each ordered item\n6. If insufficient stock: **OrderStockReductionFailed** event is published\n\n## Database\n\nThe application uses H2 in-memory database for simplicity. Access the H2 console at:\nhttp://localhost:8080/h2-console\n\n- JDBC URL: `jdbc:h2:mem:testdb`\n- Username: `sa` \n- Password: (empty)\n\n### Database Schema\n\nThe application creates tables for:\n- **orders** and **order_items** - Order management\n- **products** - Product catalog\n- **bank_accounts** and **transactions** - Banking example\n- Proper foreign key relationships and constraints\n\n## Technical Implementation Details\n\n### MapStruct Configuration\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.mapstruct\u003c/groupId\u003e\n    \u003cartifactId\u003emapstruct\u003c/artifactId\u003e\n    \u003cversion\u003e1.5.5.Final\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Java 24 Compatibility\nThe project includes configuration for Java 24 compatibility:\n- Maven Surefire plugin with dynamic agent loading\n- Experimental Byte Buddy support for Mockito\n- Proper module system configuration\n\n### Testing Strategy\n- **Unit Tests**: Domain logic and service layer testing\n- **Integration Tests**: Cross-context communication testing  \n- **Mockito**: Service mocking with Java 24 compatibility\n- **Spring Boot Test**: Full application context testing\n\n## Key Design Decisions\n\n1. **CQRS with Single Datastore**: Simplified deployment while maintaining read/write separation\n2. **Shared Package Structure**: Clear separation of shared components in CQRS contexts\n3. **Integration Events**: Proper bounded context boundaries instead of direct dependencies\n4. **MapStruct Over Manual Mapping**: Compile-time safety and performance\n5. **Spring Events**: Leveraging framework capabilities for event-driven architecture\n6. **Value Objects**: Immutable objects for type safety and domain expressiveness\n\nThis implementation showcases modern DDD practices with practical Spring Boot integration, demonstrating how to build maintainable, scalable applications with clear architectural boundaries.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhpalma%2Fddd-verticalslice-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhpalma%2Fddd-verticalslice-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhpalma%2Fddd-verticalslice-example/lists"}