> ## Content Index
> Fetch the complete content index at: https://blog.ecotone.tech/llms.txt
> Use this file to discover other available public pages before exploring further.

# Build Laravel Application using DDD and CQRS with Ecotone
- URL: https://blog.ecotone.tech/build-laravel-application-using-ddd-and-cqrs/
- Published: 2022-04-21T20:25:22.000Z
- Updated: 2024-03-02T16:24:31.000Z
- Description: DDD becomes more and more popular in PHP World, check how to implement DDD Application in Laravel using Ecotone Framework
- Author: Dariusz Gafka
- Tags: #Migrated-1709378337494, #Import 2024-03-02 11:19

DDD becomes more and more popular in PHP World and there are a lot of discussions on [how to approach it](https://twitter.com/matthiasnoback/status/1516379161325187072?ref=blog.ecotone.tech).  
In Laravel community it’s [getting momentum too](https://twitter.com/PovilasKorop/status/1517034905682812929?ref=blog.ecotone.tech).

Have you been wondering how can it be implemented in Laravel?  
In this article I will explain basics of DDD building blocks and how can we use them in Laravel Application.

It’s not required, however I encourage you to take a look on previous blog about CQRS [“Going into CQRS with PHP”](https://blog.ecotone.tech/cqrs-in-php/) before starting.

### Eloquent ORM and DDD

In DDD we are using *Domain Models*, which are different from *Eloquent Models.*  
Domain Models are clean from infrastructure and Framework related implementation, in order to have full control over modifications and extensions.

> Domain Models are meant to solve business related problems not technical ones.  
> Thanks to that it’s easier to maintain and extend them.

If we decided to use Eloquent and mix it with Domain Model, then we’ve introduced database dependency.  
However we did it for a reason, as we want to reap benefits that Eloquent integration brings.

> Fighting your own framework may bring higher complexity into the code base and make increase maintainability cost.

For building Domain Models without Eloquent there will be a separate blog post, in this one we will focus on, what we can achieve, if we decided to go hand in hand with Eloquent ORM.

![](https://storage.ghost.io/c/e5/b1/e5b187a1-f2f4-4598-915c-3030585b73e6/content/images/2024/03/1-xjfmpwp3qzkkvebvp9wsca-jpeg.jpg)

### Aggregates

In DDD we build `Aggregates which are classes rich in behaviour`.  
As an example let's take `Article`, which may be be `published`, however first need to be `approved` by the author.

This could be Eloquent Model, that we would store in database using `->save()` method.  
It's important to expose actions (methods) on the Aggregate and make use it as the only way to modify the data.  
Calling insert and updates SQLs directly on the database, may introduce incorrect data or bypass our constraints.

> If the only way to modify given aggregate is through his public methods and methods are protecting it’s own state inside, then we come the place where our models are always valid.

### Value Objects

The part of the model are Value Objects.  
VO’s are classes that are immutable. They are wrappers for given types that needs validation.

*If we have Value Object like Email in system, then we can pass it around and be sure, it’s always valid one. This decrease amount of guard logic within the system.*

### Enable Ecotone with Laravel

To enable Ecotone with Laravel install:

```
composer require ecotone/laravel
```

For automatic serialization and deserialization:

```
composer require ecotone/jms-converter
```

### Eloquent Creating new Aggregate

We will implement `Issue` aggregate. Issues can be reported by our customers in case of system errors.  
Let's start by defining `ReportIssue Command`.

In order to execute the `ReportIssue`, we need to call `Command Bus`.

What comes from `$request->all()` return data from `HTML Form` which is:

```
["email" => "johnybravo@gmail.com","content" => "My PC is not working"]
```

The `Email` inside the `ReportIssue` is Value Object Class, so we need to know how to convert from `string` to `Email` class. In order to do it we will register `Converter`.

> Ecotone JMS Converter package will handle all deserialization from Arrays / JSON / XML to PHP classes and other way around.

Let’s implement our Eloquent `Issue Aggregate`:

1. We mark our Model with `#[Aggregate]` so Ecotone can find it
2. We enable factory method under `"issue.report"` routing key.
3. As we want to publish event which contains `Id` we need to save `Issue` inside the factory method, so the identifier will be assigned
4. We publish `IssueWasReported` using `recordThat` method, which comes from `WithAggregateEvents` trait.
5. We need to expose public method with identifier for Ecotone `#[AggregateIdentifierMethod("id")]`

Now we can execute our `Controller we have defined previously to send Command and create new Issue`.

### Changing The Aggregate Issue

Now we can add possibility to close the Issue.

> There is no Command Class defined for Command Handler and that’s because we do not need any data in here. When needed Ecotone allows for seamless routing to given Handlers by routing name only.

Now we want to execute this Command Handler

The `metadata` part are extra information, that are not part of the Command itself.  
Ecotone use it to pass around framework related information.  
By passing `aggregate.id` we tell Ecotone which `Issue Aggregate it should execute`.

> You may use metadata to pass your own extra details that you would like to pass alongside with Command for example `User Id`.

### Event Handling

When `Issue` aggregate was reported we are publishing event:

We can register subscriber, that will send Email with confirmation to the customer after Issue was reported.

To `subscribe to specific Event we type hint given class as first parameter` (just like with Command Handler) and mark method with `#[EventHandler]`.

### Summary

`Ecotone Framework` is handling glue code and providing building blocks, so we can build applications quickly and in solid way.  
It integrates with Laravel and Eloquent in way those Frameworks were designed.  
And in case of need allow you to extend your application with new functionalities like [Event Sourcing](https://blog.ecotone.tech/implementing-event-sourcing-php-application-in-15-minutes/) and [Asynchronous communication](https://blog.ecotone.tech/asynchronous-php/).

If you want to run Demo Application with `Laravel and Ecotone` you can find it under [this repository](https://github.com/ecotoneframework/php-ddd-cqrs-event-sourcing-symfony-laravel-ecotone?ref=blog.ecotone.tech).