codelytv / php-ddd-example Goto Github PK
View Code? Open in Web Editor NEW🐘🎯 Hexagonal Architecture + DDD + CQRS in PHP using Symfony 6
Home Page: https://pro.codely.tv/library/ddd-en-php
🐘🎯 Hexagonal Architecture + DDD + CQRS in PHP using Symfony 6
Home Page: https://pro.codely.tv/library/ddd-en-php
We should standardize the _default
parameters of the project in order to avoid having to define them on every single Dependency Injection Container configuration file.
Yes, I see the listeners like CreateNotificationOnVideoCreated
and event handlers executor ConsumeDomainEventsCommand
but seems no one publish Domain Events like VideoCreatedDomainEvent
to the RabbitMQ or SymfonySyncEventBus
using notify
method. Isn't it? Please help me, I am confused. Thanks.
UPD: yes, out the box we use SymfonySyncDomainEventPublisher
to publish events synchronously, but anyways no one executes the handlers of them.
Modify the Dependency Injection Container definition to use the autowiring feature while instantiating Application Services and Infrastructure ones
tests/src/Mooc/Videos/VideoModuleUnitTestCase.php
In order to mock different infrastructure (repositories, external services)
We should store the tests execution result in order to see the timing evolution in CircleCI.
I don't know why, but despite having configured it in the make test
command, and in the CircleCI config, it's not storing the test results and showing them in CircleCI.
The problem wouldn't be with something related to CircleCI because it doesn't generate the XML report even when running the tests locally with the make test
command :/
Also use its bus
Hi,
I just started learning DDD and Hexagonal architecture. The code here is very interesting and I'm learning from it a lot, so thanks for that :)
I just have one question. Where would you hash passwords?
I noticed the code for comparing password is inside CodelyTv\Backoffice\Auth\Domain\AuthPassword
class. Is this the right place to hash the passwords before they would be persisted?
Please see attached file
make build error.txt
When goes to url http://api.codelytv.localhost:8030/health-check to the API health check page, show a warning:
Warning: file_put_contents(/app/apps/mooc/backend/var/cache/test/CodelyTv_Apps_Mooc_Backend_MoocBackendKernelTestDebugContainerDeprecations.log): failed to open stream: No such file or directory
The problem is with permissions when execute make build i need sud and create fies with root.
When solve this return: {"mooc-backend":"ok","rand":1}
Al ejecutar el make build me da el siguiente error:
Makefile:39: recipe for target 'start' failed make: *** [start] Error 127
En la liniea 39 de Makefile hay:
@docker-compose $(CMD)
Tenéis la interfaz middleware en infraestructura https://github.com/CodelyTV/cqrs-ddd-php-example/blob/master/src/Shared/Infrastructure/Bus/Middleware/Middleware.php
Está clase no debería ir en dominio, enlazado a esto habría algún caso de uso que provocara tener una interfaz en infraestructura?¿
I tried to use it on windows 10 but if I do make build powershell gives some errors
process_begin: CreateProcess(NULL, pwd, ...) failed. Do not run Composer as root/super user! See https://getcomposer.org/root for details Composer could not find a composer.json file in /app To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section make: *** [composer-install] Erreur 1
I fixed that just changing pwd and making it cross system compliant from
I've removed
Or we could simply have two different make files one for windows and one for linux.
But even if I try to do all the changes to make it works I still getting some errors...
I changed
composer-install: @docker run --rm --interactive --tty --volume $(shell pwd):/app --user $(id -u):$(id -g) \ gsingh1/prestissimo install \ --ignore-platform-reqs \ --no-ansi \ --no-interaction
to
composer-install: @docker run --rm --interactive --tty --volume ${PWD}:/app gsingh1/prestissimo install --ignore-platform-reqs --no-ansi --no-interaction
Still getting this error:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Composer could not find a composer.json file in /app
To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section
make: *** [composer-install] Erreur 1
I don't know why because if I execute the command directly in powershell all seems ok:
docker run --rm --interactive --tty --volume ${PWD}:/app gsingh1/prestissimo install --ignore-platform-reqs --no-ansi --no-interaction
Maybe it's related to make but I don't really know much about it...
We're still using the deprecated CircleCI 1.0 version for this project. It's no longer maintained, so we should upgrade to the 2.0 version.
Add a new top level section to the README.md
file with the following contents:
VideoRepository#searchByCriteria(Criteria $criteria): Videos;
method while searching Videos
using different Criteria
. Common use case for the backoffice of our applicationsImportant: We should reference a piece of code illustrating each one of the use cases or patterns. Something very similar to what we've done in the Scala API repo with the Libraries and implementation examples README.md
section
We finally have a stable release of the Behat support for Symfony 4 🎉
Here we have all the information regarding the good news 🙂
Some cosa fina news 😬:
The extension provides a dependency injection configuration which automatically finds your contexts and autowires them:
# config/services_test.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\Tests\Behat\:
resource: '../tests/Behat/*'
😱😱😱
Structure the README.md
file of this project following the same sections of the Scala HTTP API one
Hello, and first, thanks you to sharing this project, you made a great job. I'm trying to figure out why a raw sql mapping is used instead of directly using the mapping of entities (*.orm.xml
). Could you explain it to me please. It make sense for performance, for the tests (initialisation time) ? or for more granular definition of database ? I'm trying now to use the xml mapping first (at place of EntityManagerFactory::generateDatabaseIfNotExists
) but it seems to be a headache mission.
I do not have composer installed on my local computer and I see that it is not installed in the php docker container, is there a way to install a dependency in the project that I am not seeing? or do I have to install composer on my local computer?
We should be able to run the tests from inside the PHP Docker container
Hola, i need to split operations, so i tried to add a command bus into a command handler with the usage of InMemorySymfonyCommandBus. I have this issue:
Error {#855
#message: "Maximum function nesting level of '256' reached, aborting!"
#code: 0
#file: "./var/cache/dev/ContainerUxFsxIU/App_KernelDevDebugContainer.php"
#line: 1800
trace: {
./var/cache/dev/ContainerUxFsxIU/App_KernelDevDebugContainer.php:1800 {
ContainerUxFsxIU\App_KernelDevDebugContainer->ContainerUxFsxIU\{closure}^
›
› return $this->privates['App\\Shared\\Infrastructure\\Bus\\Command\\InMemorySymfonyCommandBus'] = new \App\Shared\Infrastructure\Bus\Command\InMemorySymfonyCommandBus(new RewindableGenerator(function () {
› yield 0 => ...
A idea ?
In the file applications/api/web/api.php
in Request::setTrustedProxies
is needed a second parameter called $trustedHeaderSet
of type Request::HEADER_*
Buenas chicos, antes de nada gran curso.
Tengo una duda de concepto con respecto a ddd y como se manejaría con doctrine:
Imaginémonos que tenemos una clase User (que todos sabemos que no para de crecer y crecer sin darnos cuenta) y queremos dividirla en contextos para evitar que la clase tenga toda la lógica centralizada de todos los casos de uso que se puedan dar, como lo resolveríais y como manejaríais el mapeo con doctrine?
Por ejemplo imaginémonos una red social, user tiene cierta lógica que se aplica en la autenticación (registrar, login...) y luego otra lógica que se da en la parte de amigos (agregar amigo, borrar amigo...)
Usaríais una clase abstracta BaseUser con las propiedades básicas del usuario (userId y username) y extenderíais de ella en función del contexto?, es posible manejar esto con doctrine?
Gracias de antemano chicos ;)
This was missing from #15
We need:
Since https://github.com/CodelyTV/cqrs-ddd-php-example/pull/90/files#diff-98c12a693941ae3c4f50872403416471R27 we're using the moock_backend
kernel. In the moment we'll have more than 1 this could fail.
Follow the same principles as in the Scala API repo
You can copy the very same pre-push
script just modifying the command to execute. That is, instead of calling to sbt prep
, we should call to a command defined in the composer.json
in order to run PhpStan, CodeSniffer, acceptance tests, and unit tests.
This issue includes the addition to the README.md
of this pre-push
script as in the Scala API Repo 🙂
Based on the discussions regarding this PR.
We should model the MessageId
<- EventId
|RequestId
<- QueryId
|CommandId
hierarchy being Value Objects wrapping a Uuid
. We should also model their corresponding test stubs.
In the CQRS course there has been one doubt regarding if the VideoResponse
was an actual domain model, or if it was a query response DTO.
We're currently storing the responses DTOs in the Domain folder which could lead to confusion. What do you think @rgomezcasas about moving these DTOs to the Application subfolder? (In this example, the Find
one)
To a parallel test
folder making it easier to find the test you're looking for
There is a typo with the namespace CodelyTv\Mooc\Courses\Infraestructure\Persistence
Infraestructure
should be Infrastructure
?
Hey, thanks a lot for the repo.
I've tried to play with the repository and I wanted to see where would you do validation?
I've created a video with a non existent course.
I wonder how would you do if you wanted to validate that the course exists ?
Thanks in advance :)
Hey guys,
I found this repository today and it looks very interesting.
Can I find somewhere your video presentation in English?
Cheers!
Publish the PHP Docker image to DockerHub registry in order to speedup local environment setup and CircleCI builds times.
rgomezcasas
)After installing if you try to go to
http://api.codelytv.dev:8030/status
It doesn't work probably because .dev is now a valid domain name (by Google).
You should change this domain, I switched in my hosts (in Windows 10) from this to
127.0.0.1 api.codelytv.local
And now going to http://api.codelytv.local:8030/status works as intended giving me status 200 ok.
I suggest you to use traefik to avoid any futur problems.
It's a reverse proxy so you don't need to configure your hosts anymore since traefik will handle this.
https://github.com/containous/traefik
I can integrate it in your docker-compose.yml if you want.
@rgomezcasas @JavierCane Just tell me and I'll do a pull request with this.
The good thing with traefik is if you want after to go "live" it's easier too since it supports automatic certificate generation (let's encrypt) and you just have to change the domain name (in your env or wherever you want).
Instead of instantiating the Value Objects directly from the controller, we should instantiate a DTO such as SignUpUserRequest
and pass it to the Application Service.
The Application Services intended for querying data, we should return also a DTO such as UserResponse
.
This way we:
UserId
value objects and so on).XxxRequest
by their corresponding XxxCommand
,XxxRequest
Sigo los pasos para instalar la aplicación y al ir a la url "http://api.codelytv.localhost:8030/status" me sale el siguiente error:
We've already added Docker Compose to this repository thanks to the @sdecandelario PR: #56
However, we had an interesting discussion about how we should implement the etc/infrastructure/php/Dockerfile
for the PHP container specifically regarding the provision (composer install
) phase.
Provisioning in an early stage of the Dockerfile
would allow us to perform some optimizations 😬
One of these optimizations would be applying the builder pattern or Multistage builds. You can read more information about them in the "Docker: De 0 a deploy" CodelyTV Pro course by @fiunchinho (here you have the course repository with some examples), and a blog post about this technic and its benefits.
However, we've tried to apply this strategy and we've miserably failed (🤣). The reason why we haven't been able to do so is because the PHP Dockerfile
is in a subdirectory and it can't copy the composer.json
file (it is inside the parent folder).
We don't want to move the PHP Dockerfile
to the project root folder because it would add too much noise, but we don't know the best way to have the needed files available. Any suggestions?
Estaría super bien crear un grupo de slack o discord en que los alumnos y algunos tutores podamos charlar de los distintos temas de la plataforma (ddd, tdd, php, symfony, docker...)
Sorry de antemano si este no es el mejor lugar para comentar esto.
Un abrazo chicos.
I came across this error while trying to access http://api.codelytv.localhost:8030/
Attempted to call an undefined method named "getException" of class "Symfony\Component\HttpKernel\Event\ExceptionEvent".
To make it work, I changed a few things in this class:
which results in the following:
final class ApiExceptionListener
{
private ApiExceptionsHttpStatusCodeMapping $exceptionHandler;
public function __construct(ApiExceptionsHttpStatusCodeMapping $exceptionHandler)
{
$this->exceptionHandler = $exceptionHandler;
}
public function onException(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
$event->setResponse(
new JsonResponse(
[
'code' => $this->exceptionCodeFor($exception),
'message' => $exception->getMessage(),
],
$this->exceptionHandler->statusCodeFor(get_class($exception))
)
);
}
private function exceptionCodeFor(\Throwable $error): string
{
$domainErrorClass = DomainError::class;
return $error instanceof $domainErrorClass ? $error->errorCode() : Utils::toSnakeCase(get_class($error));
}
}
These are not optimal changes by any means, but they allowed me to display a fully functionnal error message on the homepage.
Are there examples of implementation AsyncRequestGetController?
file_put_contents(/app/apps/mooc/backend/var/cache/test/CodelyTv_Apps_Mooc_Backend_MoocBackendKernelTestDebugContainerDeprecations.log): failed to open stream: No such file or directory
Unable to create the cache directory (/app/apps/mooc/backend/var/cache/test)
This errors show when I go to health check route after make build
.
I don't know how to resolve. Any help?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.