PHP Microservice example using DDD, Hexagonal and best practices
This is a repo containing a PHP application using Domain-Driven Design (DDD) and Command Query Responsibility Segregation
(CQRS) principles.
It's a basic implementation of a User - Role manager. There is a version implemented using Lumen framework and another one using Symfony framework.
Both shares the same domain
logics implemented in the src
folder.
Report a bug
·
Request a feature
Installation
Requirements
Environment
- Clone this project:
git clone https://github.com/mguinea/php-ddd-microservice-example php-ddd-microservice-example
- Move to the project folder:
cd php-ddd-microservice-example
- Create a local environment file
cp .env.example .env
- Change (if required) ports and any other environment variables in
.env
file
Execution
Install all the dependencies and bring up the project with Docker executing: make install
Then you'll have 2 apps available (an api made using Lumen and the same one made using Symfony):
- Lumen API: http://localhost:8180/lumen/api/v1/health-check
- Symfony API: http://localhost:8180/symfony/api/v1/health-check
Tests
Install the dependencies if you haven't done it previously: make composer-install
Execute all test suites: make tests
Monitoring
TODO
Project structure and explanation
Bounded contexts
src
folder contains the bounded context responsible for the management of users and roles and their relations.
Architecture and Structure
This repository follows the Hexagonal Architecture pattern. Also, it's structured using modules. With this, we can see that the current structure of the Bounded Context is:
$ tree -L 2 src
src
├── Application
│ ├── Role
│ └── User
├── Domain
│ ├── Role
│ ├── Shared
│ └── User
└── Infrastructure
├── Role
├── Shared
└── User
Repositories
Repository pattern
Our repositories try to be as simple as possible usually only containing basic CRUD methods (delete, find, save and search).
If we need some query with more filters we use the Specification pattern also known as Criteria pattern. So we add a searchByCriteria
method.
Implementations
There is an implementation using Eloquent
for Lumen
and another one made by using PDO
for Symfony
CQRS
We are using symfony messenger
to implement buses for Lumen and Symfony implementations.
My conventions
There are some opinionated resolutions / approaches in this project.
Generic methods (CRUDs)
get
retrieve an entity. If not found, throws an exception.find
retrieve an entity. If not found, return null.delete
delete an entity. If not found, throws an exception.create
create an entity. If found, throw an exception.update
update an entity. If not found, throws an exception.search
retrieve a collection of entities by criteria. If nothing found, returns an empty collection.listing
retrieve a collection of entities with no criteria. If nothing found, returns an empty collection.