This repository contains a PHP application structured following Domain-Driven Design (DDD) and Command Query Responsibility Segregation (CQRS) principles, powered by Caddy web server for optimal performance and security.
Report a bug ·
Request a feature
- Clone the repository
git clone https://github.com/XRaspall/laravel-cqrs-ddd-skeleton
- Enter the project folder
cd laravel-cqrs-ddd-skeleton
- Copy the
.env.example
file to.env
cp .env.example .env
- Build and start the Docker containers
docker-compose up -d
- Install the PHP dependencies
docker-compose exec php-laravel-cqrs composer install
- Generate application key
docker-compose exec php-laravel-cqrs php artisan key:generate
- Run database migrations
docker-compose exec php-laravel-cqrs php artisan migrate
- Access the application:
- Web application: http://localhost
- PHPMyAdmin: http://localhost:8080
- Username: laravel
- Password: secret
The project uses Caddy as web server with the following features:
- Automatic HTTPS (disabled by default)
- FastCGI for PHP processing
- Gzip compression
- Static file serving
To view logs:
docker-compose logs -f
To stop the containers:
docker-compose down
├── .docker/ # Docker configuration files
│ ├── caddy/ # Caddy web server configuration
│ └── php/ # PHP-FPM configuration
├── bootstrap/ # Laravel Bootstraping
├── config/ # Laravel configuration files
├── database/ # Database migrations and seeders
├── public/ # Public entry point and assets
├── resources/ # Frontend resources
├── src/
│ ├── App/ # Application modules
│ │ └── User/ # User module
│ │ ├── Application/ # Application layer
│ │ │ ├── Commands/ # Command handlers and DTOs
│ │ │ └── Queries/ # Query handlers and DTOs
│ │ ├── Domain/ # Domain layer
│ │ │ ├── Entities/ # Domain entities
│ │ │ ├── Exception/ # Domain exceptions
│ │ │ └── Contracts/ # Domain interfaces
│ │ ├── Infrastructure/ # Infrastructure layer
│ │ │ ├── Providers/ # Infrastructure providers
│ │ │ ├── Repositories/ # Repositories implementations
│ │ │ └── Services/ # External services
│ │ └── Presentation/ # Presentation layer
│ │ ├── Controllers/ # HTTP controllers
│ │ ├── Requests/ # Form requests
│ │ └── Routes/ # Module routes
│ └── Shared/ # Shared components and utilities
│ ├── Infrastructure/ # Shared infrastructure components
│ ├── Domain/ # Shared domain components
│ └── Presentation/ # Shared domain presentation components
├── tests/ # Test suites
│ ├── Unit/ # Unit tests
│ ├── Integration/ # Integration tests
│ └── Feature/ # Feature tests
This project follows a clean architecture approach with DDD and CQRS patterns, organized in modules:
- Organized in modules (e.g., User)
- Each module follows clean architecture with four layers:
- Application: Contains commands and queries
- Domain: Contains business logic, entities, and interfaces
- Infrastructure: Contains implementations of interfaces, repositories and external services
- Presentation: Contains controllers, requests, and module routes
- Contains reusable components across modules
- Includes shared infrastructure implementations
- Provides common domain components
- Reduces code duplication
- Modular Architecture: Each module is self-contained with its own layers
- Clean Architecture: Clear separation of concerns with four distinct layers
- CQRS Pattern: Separates read and write operations for better scalability
- DDD Principles: Rich domain model with encapsulated business logic
- Docker Environment: Development environment with Caddy, PHP-FPM, and MySQL
- Testing Structure: Organized test suites for different testing levels
-
Module Organization
- Keep module-specific code within its module
- Follow the four-layer architecture in each module
- Use shared components for common functionality
-
Layer Responsibilities
- Application: Orchestrate use cases and handle commands/queries
- Domain: Define business rules and interfaces
- Infrastructure: Implement interfaces and handle external concerns
- Presentation: Handle HTTP requests and responses
-
Domain Logic
- Keep business rules in the domain layer
- Use value objects for immutable concepts
- Implement domain events for side effects
-
Commands & Queries
- Commands should be named in imperative form (e.g.,
CreateUserCommand
) - Queries should be named in question form (e.g.,
GetUserByIdQuery
) - Use DTOs for data transfer between layers
- Commands should be named in imperative form (e.g.,
-
Testing
- Write unit tests for domain logic
- Use integration tests for infrastructure
- Implement feature tests for use cases
-
Code Organization
- Keep related code close together
- Use interfaces for dependencies
- Follow SOLID principles