This is a pet project for DDD and Clean/Hexagonal architecture concepts.
- Introduction
- Domain/ Application / Infrastructure
- Project setup
- Services
- Composer / Unit Tests
- HTTP UI
- Console UI
- Metrics
We are trying to find our own way to create apps. Some parts are based on awesome DDD examples that we have recently found on Github: dddinphp, jorge07/symfony-4-es-cqrs-boilerplate, CodelyTV/cqrs-ddd-php-example, and many others
With very simple Domain:
User(id, email) can be read and created.
Implemented concepts:
- Entities, ValueObjects, DomainEvents, Exceptions and Repositories.
- Model Validation with Assert
- UID generated with ramsey/uuid
Actions: CreateUserAction and GetUserAction
- Action/Command Bus with Tactician and PDO transactional middleware.
- Event Store and Event Notifier with Prooph (PDO)
- Publishing Domain Events in a Rabbitmq Topic Exchange
- UI
- Http Handlers with Slim Framework
- Console Commands with Symfony Console
- PSR's:
- PSR-2 Coding Style Guide (codesniffer in composer.json)
- PSR-3 LoggerInterface (implemented with Monolog)
- PSR-4 Autoloader (autoload/autoload-dev in composer.json)
- PSR-7 HTTP Messages (with Slim)
- PSR-11 Container Interface (with Slim built-in container)
- PSR-15 Http Handlers and Middlewares
- Metric's services implemented with Prometheus Client.
- Http Error Handler following API Problem specification.
- Environment config with zend-config
- Development environment with Docker
- Install docker
- Clone this repo:
git clone https://github.com/jbarroso/ddd-example cd ddd-example
- Start development environment with docker-compose
export UID && docker-compose up -d
- Access to the mysql database
docker-compose exec mysql mysql -u myuser -psecret example
- Access to Rabbitmq (guest/guest) http://localhost:15672
- Access to Prometheus http://localhost:9090
- Access to Grafana (admin/admin) http://localhost:3000
Install dependencies (they are already installed with docker-compose up)
docker-compose run php composer install
Check coding style and run unit tests (phpunit)
docker-compose run php composer check
Say hello world!
curl -v -X GET "http://localhost/hello"
Create a user
curl -v -X "POST" "http://localhost/user" -H "Content-Type: application/json" -H "Accept: 1.0" -d '{"email":"[email protected]"}'
Get a user
curl -v -X GET "http://localhost/user?id=1958964c-724e-11e9-80e9-0242ac120004"
List all available commands
docker-compose run php bin/console
Say hello world!
docker-compose run php bin/console hello-world
Get a user
docker-compose run php bin/console get-user 1958964c-724e-11e9-80e9-0242ac120004
Notify events to Rabbitmq exchange:
docker-compose run php bin/console notify-events
Start a Rabbitmq consumer listening to all events. For each event it will write a log entry in logs/app.log and also it will publis a counter metric with the event name in Prometheus.
docker-compose run php bin/console all-events-consumer
Start a Rabbitmq consumer listening to UserWasCreated event. It will write a log entry in logs/app.log.
docker-compose run php bin/console user-was-created-consumer
Following Prometheus concepts we have: counters, gauges and histograms.
- The application exposes a /metrics endpoint for Prometheus and for testing porpouse it will update and publish a counter (example_some_counter), a gauge (example_some_gauge) and an histogram (example_some_histogram).
- Also we have a middleware to messure HTTP Request duration (LatencyMiddleware). It will publish example_request_duration_seconds histogram.
- AllEventsConsumer will increase a counter wit the event name (example_UserWasRead and example_UserWasCreated).
- And finally we have configured with Docker a Rabbitmq Prometheus exporter that you can consume in Grafana with this dashboard: Rabbitmq Graphana dashboard.