CodelyTV / php-ddd-example
- вторник, 11 февраля 2020 г. в 00:19:46
PHP
🐘 🎯 Hexagonal Architecture + DDD + CQRS applied in PHP using Symfony 5
Example of a PHP application following Domain-Driven Design (DDD) and
Command Query Responsibility Segregation (CQRS) principles keeping the code as simple as possible.
Take a look, play and have fun with this.
Stars are welcomed
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
git clone https://github.com/CodelyTV/cqrs-ddd-php-example cqrs-ddd-php-examplecd cqrs-ddd-php-examplecp .env .env.localapi.codelytv.localhost domain to your local hosts: echo "127.0.0.1 api.codelytv.localhost"| sudo tee -a /etc/hosts > /dev/nullmake buildmake depsmake testThis project tries to be a MOOC (Massive Open Online Course) platform. It has a Web, an API and some Consumers.
This repository follow the Hexagonal Architecture pattern. Also is structured using modules.
With this, we can see that the current structure of a Bounded Context is:
$ tree -L 4 src
src
|-- Mooc // Company subdomain / Bounded Context: Features related to one of the company business lines / products
| `-- Videos // Some Module inside the Mooc context
| |-- Application
| | |-- Create // Inside the application layer all is structured by actions
| | | |-- CreateVideoCommand.php
| | | |-- CreateVideoCommandHandler.php
| | | `-- VideoCreator.php
| | |-- Find
| | |-- Trim
| | `-- Update
| |-- Domain
| | |-- Video.php // The Aggregate of the Module
| | |-- VideoCreatedDomainEvent.php // A Domain Event
| | |-- VideoFinder.php
| | |-- VideoId.php
| | |-- VideoNotFound.php
| | |-- VideoRepository.php // The `Interface` of the repository is inside Domain
| | |-- VideoTitle.php
| | |-- VideoType.php
| | |-- VideoUrl.php
| | `-- Videos.php // A collection of our Aggregate
| `-- Infrastructure // The infrastructure of our module
| |-- DependencyInjection
| `-- Persistence
| `--MySqlVideoRepository.php // An implementation of the repository
`-- Shared // Shared Kernel: Common infrastructure and domain shared between the different Bounded Contexts
|-- Domain
`-- InfrastructureOur repositories try to be as simple as possible usually only containing 2 methods search and save.
If we need some query with more filters we use the Strategy pattern also known as Criteria pattern. So we add a
searchByCriteria method.
You can see an example here and its implementation here.
You can see an example of an aggregate here. All aggregates should extends the AggregateRoot.
There is 1 implementations of the command bus.
The Query Bus uses the Symfony Message Bus.
The Event Bus uses the Symfony Message Bus. The MySql Bus uses a MySql+Pulling as a bus. The RabbitMQ Bus uses RabbitMQ C extension.
There are some things missing (add swagger, improve documentation...), feel free to add this if you want! If you want some guidelines feel free to contact us :)
This code was show in the From framework coupled code to #microservices through #DDD talk and doubts where answered in DDD y CQRS: Preguntas Frecuentes video.