Comments (13)
Even though I'm often not actually serializing DTO's, I like them to be very flat, since that's in the spirit of a DTO. Any type of object would not be able to cross application boundaries (within the application it would probably cause incorrect coupling and to the world outside it would be completely impossible ;)).
from php-ddd.
My general rule is to have only immediately serializable data in a DTO (that is, primitive types). I know some people who add "getters" to a DTO which produce actual (domain) objects based on those primitive values. I don't do it like that, but always explicitly convert to objects inside the command handler.
from php-ddd.
I'm using commands and view models which have primitive types and won't throw any exceptions. I think this is a useful aspect of them. For commands it's very useful because now (if you use Symfony) the Form component can populate it, and validate it afterwards. Then if you pass the command to the application service, it will use the raw data from the command to construct value objects and entities. So any violations of domain invariants will appear in the application service only.
from php-ddd.
What about date
s? Should they be passed as ImmutableDateTime
objects or as primitive strings?
What do you think @matthiasnoback?
from php-ddd.
Agree! But do you even handle dates as strings instead of DateTimeImmutable?
from php-ddd.
Having them always serializable is good for offloading to external queue.
If serializing with an serializer like symfony/serializer or jms' it should be fine to even use object types as properties since they would be denormalized as expected. DateTime would be no problem then.
from php-ddd.
Thanks for your opinion!
Currently I'm using DateTime
objects in my DTO. But I will switch to a string yyyy-mm-dd
transfer.
For now most of my commands are populated by Symfony Forms (e.g. via LexikFormFilterBundle
by @lexik) using the data_class
.
But soon we will have primitive request parameters e.g. JSON format. Not sure if the UI would actually pass a Javascript Date object. But most of the times dates come from datepickers that return the desired string.
Converting the date strings to DateTime
objects in my handler instead will make my commands flexible for any format resp. "application boundaries".
from php-ddd.
@webdevilopers DateTime::ATOM can be parsed by php and js natively.
from php-ddd.
Even though I'm often not actually serializing DTO's, I like them to be very flat, since that's in the spirit of a DTO. Any type of object would not be able to cross application boundaries (within the application it would probably cause incorrect coupling and to the world outside it would be completely impossible ;)).
I've been using Commands w/ value objects form a long time. But now that we are working with DTOs for read models from projections in a DDD CQRS environment I'm thinking about switching back again.
Recently there is discussion going on wether Commands (and Handlers) belong to the Domain Layer too:
#32
Currently having Commands using Value Objects would even support this Credo.
But moving back to a DTO with primitive would clearly separate it from the Domain Layer keeping it in the Application Layer.
And that makes it easier for our UI team to identify tasks:
The reason for this is that our UI Tasks are reflected directly by the commands. That makes it easier to talt to our UI developers by "keeping them away" from our Domain Layer. ;)
Our handler than "converts" the UI Task into our "Domain intention":
PlaceOrder(Command) -> PlaceOrderHandler -> Order::place($command->orderId())
In the end the Application Layer somehow has to be aware of the Domain Layer. At least when transforming the primitive types to Value Objects and then pass them to the Domain Model.
Though I think "Actor Models" also directly accept the Commands inside the Model and then transform them there. The Application Layer and orchestration is "skipped".
Any thoughts about that?
Similar discussion:
- https://stackoverflow.com/questions/4869473/value-objects-in-cqrs-where-to-use
- https://softwareengineering.stackexchange.com/questions/378909/in-what-layer-are-the-dtos-stored-with-cqrs
from php-ddd.
Another advantage of moving the validation of creating object to the Handler would be the improvement of catching errors in a single place e.g.:
#4
from php-ddd.
That is exactly the approach I would like to use @matthiasnoback in the future.
Besides the validation it will also make it easier to work with my team since some members ca focus and designing the Controllers in a different Layer / Namespace maybe.
Thanks for the feedback!
from php-ddd.
Cool, you're welcome.
from php-ddd.
We are currently decoupling our UI from our (mostly Symfony w/ Forms) applications. Now we no longer separate between a "CommandDTO" and the actual "Domain Command". The latter is sometimes directly passed to an aggregate root.
This solution by @vkhorikov works fine for us:
-
A controller receives a ChangedEmailDto from the external client. Because that’s a DTO, meaning that its sole purpose is to transfer data from one application to another, it consists of primitive types only.
-
The controller transforms the DTO into a command by converting some of the primitives into Value Objects (string email into Email email in the above example, where Email is a Value Object) and passes that command to a command handler (the application services layer).
-
The command handler executes the command by coordinating the work between domain classes (including the already dehydrated Email Value Object).
-
The domain model generates domain events. Domain events may also contain value objects — for the same reasons commands do, since both commands and domain events reside at the same level of abstraction in the onion architecture.
-
The app services layer converts the domain events into messages on the message bus. Those messages are plain DTOs too because their sole purpose is to communicate the email change to other systems.
from php-ddd.
Related Issues (20)
- Repositories inside or outside Domain Services HOT 1
- Event Enriching and external changes to read-model data
- When, where and how to create Summary Events HOT 3
- Passing read models (value objects representing state) / domain service to aggregate methods HOT 6
- Unit testing value objects with internal datetime calculation HOT 14
- How to test application service command handlers dealing with read models? HOT 12
- Process Manager example with Symfony Messenger Command / Event Bus and ProophOS HOT 5
- Batch / Bulk operations handling multiple event-sourced aggregate roots HOT 3
- How to use factory methods on aggregates in CQRS - WRITE vs. READ model HOT 1
- How to keep read-models up-to-date when a name property was externally changed?
- How to upcast events with Prooph HOT 1
- Are CQRS commands part of the domain model? HOT 13
- Populate Projection with multiple tables HOT 2
- Where to call or pass a domain service? HOT 16
- How to implement the Equatable interface / Equals or SameValueAs method in value objects
- Domain Event Publisher for Doctrine Entities HOT 1
- Event Sourcing vs. Event-Driven Architecture (EDA)
- The repository pattern HOT 4
- Properties on Domain Events HOT 3
- PHP Command DTO with Symfony Constraints equivalent in Angular Forms HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from php-ddd.