|
1 | | -Basic Symfony Flex Project With Docker + PHPUnit + PHPCS |
2 | | --------------------------------------------------------- |
| 1 | +Default DDD PHP project With Docker + PHPUnit + PHPCS + Symfony Flex (as an infrastructure artifact) |
| 2 | +---------------------------------------------------------------------------------------------- |
3 | 3 |
|
4 | 4 | Basic skeleton containing just a `/_healthcheck` endpoint, and including: |
5 | 5 | - Dockerized startup (with PHP-FPM, check `/docker` folder and the `README.md` in there). |
@@ -31,4 +31,51 @@ If you consider the dockerized environment good enough to production, remember t |
31 | 31 | You can see a reasonably good performance by executing |
32 | 32 | [Apache Bench tool](https://httpd.apache.org/docs/2.4/programs/ab.html), |
33 | 33 | with around 100s of requests in 10s concurrent: |
34 | | -`ab -n 100 -c 10 http://localhost:8000/_healthcheck` |
| 34 | +`ab -n 100 -c 10 http://localhost:8000/_healthcheck` |
| 35 | + |
| 36 | +## Project architecture |
| 37 | +This project is architectured according to a DDD + CQRS pattern, which will contain three main parts: |
| 38 | +- __Domain__: represents business concepts and business logic. It should not know anything about the other parts |
| 39 | +- __Application__: defines jobs and orchestrate domain objects to solve problems. It just can know about `Domain` |
| 40 | +- __Infrastructure__: responsible of Ui (Controllers) / Console / 3rd parties concerns. |
| 41 | +This can know about `Application` and `Domain`. |
| 42 | + |
| 43 | +## Project structure |
| 44 | +Extending the previous architecture, this is the main folder structure within the project |
| 45 | + |
| 46 | +``` |
| 47 | +Domain |
| 48 | +└─── Exception: Contains `AppException`, responsible for any exception about the application which |
| 49 | +| will contain an internal error code, plus a collection of error codes along the app |
| 50 | +| |
| 51 | +└─── Model: Core business logic within the aplication, which will also contain validations |
| 52 | +| |
| 53 | +└─── Repository: Interfaces to access the data model that shall be viewed as a Collection, with a composition as follows: |
| 54 | + └─── `findOfId`: Find a specific Model from a given unique ID. Ideally returns a Domain exception when not found |
| 55 | + └─── `findOfXxx`: Find the Model through an unique ID |
| 56 | + └─── `save`: responsible of create/update the model |
| 57 | + └─── `delete`: responsible of delete the model from the collection |
| 58 | +
|
| 59 | +
|
| 60 | +Application |
| 61 | +└─── Command: Executes an use case by orchestrating domain objects, and ideally produces an output in the shape of an event |
| 62 | +| |
| 63 | +└─── Query: Interfaces of specialized queries (anythin different of a `findOfId`) to the model. |
| 64 | + | Note: those are part of the Application because the Domain should not be aware at all about the expected Responses |
| 65 | + └─── Responses: Set of Value Objects which we expect to obtain as a result of the query, ideally implementing a `Serializable` |
| 66 | +
|
| 67 | +
|
| 68 | +Infrastructure |
| 69 | +└─── EventListener: Even though those could be part of the Application layer (as actors regarding different events), |
| 70 | +| right now they are an infrastructure concern as the infra too is implemented as an Event schema. |
| 71 | +| |
| 72 | +└─── Query: Contains folders with the different sources of implementation per query (e.g., `MySqlPremiumUsersQuery`) |
| 73 | +| |
| 74 | +└─── Repository: Contains folders with the different sources of implementation per repository (e.g, `MySqlUsersRepository`) |
| 75 | +| |
| 76 | +└─── Service: Third-party specific implementations of services and connectors (REST, MongoDB, Stripe...) |
| 77 | +| |
| 78 | +└─── Ui: Contains the user interface communication, mainly Console commands (cron/daemons) and Web commands (controllers) |
| 79 | + |
| 80 | + |
| 81 | +``` |
0 commit comments