Can a DTO have instance methods returning derived values? - dto

Is it ever acceptable for a DTO to have instance methods which return derived values based on the DTO's data? Or should DTOs be pure data containers with no additional methods (other than getters/setters)?
The purist in me says that it is far to easy for business logic to creep into such methods. However, if (for example) a DTO is shared across application layers, then maybe there is an argument for having such methods on the DTO.
What are your views on this? Are there ever situations where it is acceptable, or should this sort of thing be avoided? And why/why not?

DTOs should not have behaviour, they are mere containers for transporting data across process boundries and should consist of setters/getters only.
It should be avoided at all costs otherwise it would be construed as misapplication of the DTO pattern.

Related

Exposed domain model in Java microservice architecture

I'm aware that copying entity classes and properties into DTOs is considered anti-pattern, so by Exposed domain model pattern the same #Entity can be used as both database entity class, and DTO for service and MVC layer. (see here https://codereview.stackexchange.com/questions/93511/data-transfer-objects-vs-entities-in-java-rest-server-application)
But suppose we have microservice architecture where the same set of properties is used as entity in one project with persistence, and as DTO in another project which uses the first one as a service. What's the proposed pattern in such a situation?
Because the second project doesn't need #Entity related functionality, and if we put that class in shared library, it will be tied unnecessary to JPA specific APIs and libraries. And the alternative is to again use separate DTO classes anti-pattern.
When your requirements for a DTO model exactly match your entity model you are either in a very early stage of the project or very lucky that you just have a simple model. If your model is very simple, then DTOs won't give you many immediate benefits.
At some point, the requirements for the DTO model and the entity model will diverge though. Imagine you add some audit aspects, statistics or denormalization to your entity/persistence model. That kind of data is usually never exposed via DTOs directly, so you will need to split the models. It is also often the case that the main driver for DTOs is the fact that you don't need all the data all the time. If you display objects in e.g. a dropdown you only need a label and the object id, so why would you load the whole entity state for such a use case?
The fact that you have annotations on your DTO models shouldn't bother you that much, what is the alternative? An XML-like mapping? Manual object wiring?
If your model is used by third parties directly, you could use a subclassing i.e. keep the main model free of annotations and have annotated subclasses in your project that extend the main model.
Since implementing a DTO approach correctly, I created Blaze-Persistence Entity Views which will not only simplify the way you define DTOs, but it will also improve the performance of your queries.
If you are interested, I even have an example for an external model that uses entity view subclasses to keep the main model clean.
Thank you for the answers, but emphasize in the question is on microservice (MS) architecture and reusing defined entity POJOs from one MS in another as POJOs. From what I've read on microservices it's closely related to another question - should MSs share any common functionality and classes at all, or be completely independent? It seems there is no definite agreement on it, and also no definite answer, or widely accepted pattern, to this.
From my recent experience here is what I adopted, and it works well so far.
Have common functionality across MSs - yes, in form of a commons project added as dependency to all MSs, with its dependencies set as optional. Share entity classes (expose them in commons) - no.
The main reason is that entity classes are closely related to data store for particular MS. And as the established rule is that MSs shouldn't share data stores, then it makes sense not to share entity classes for those data stores. It helps MSs to be more independent, and freedom to manage their data store in their own way. It means some more typing to add additional DTO classes and conversion between them, but it's a trade-off worth taking to retain MS independence. Reasons Christian Beikov and Maksim Gumerov mentioned apply as well.
What we do share (put in commons) are some common functionality and helper classes (for cloud, discovery, error handling, rest and json configuration...), and pure DTOs, where T is transfer between MSs (rest entities or message payloads).

DDD - How to store aggregates in NoSql databases

A current project needs us to persist domain objects in a NoSQL database such as mongoDB.
In many examples (incl. Eric Evans, Vaughn Vernon) the domain objects are serialized and persisted to the mongoDB directly.
We would like to avoid mixing the domain layer with persistence related inforamtion by not having any annotations in our domain objects.
Also we are concerned about corrupting the persisted data by changing the domain object in the future.
We came to the conclusion that we need to have some kind of DTOs translating between the domain objects and the persisted data.
Did anyone of you come across a good solution for such a case?
Yes. Your domain models should be ignorant of persistence. So you need a DTO or what I call data models (apart from the domain models and view models). Your data models will be map to the domain models before persisting to the database. This mapping is pretty common in insert and update operations. For read-only operations (reporting, etc) you can bypass the mapping from data models and to domain models. That will prevent loading the whole object graph of your domain models. This is widely applied in CQRS architecture patterns where read and write commands are separated.
Like you, I want business objects to have no dependency on any kind of specific repository. I solved it like this: That have your business object define its state objects and repository functions as interfaces. Your repository implementation can create an actual state object and inject that into your business object using the constructor.
There are a lot of advantages to this approach (such as having business objects for specific purposes), but you easily achieve complete (two-way) independence of your repository this way. Martin Fowler also hinted at this approach elsewhere.
I actually use the same pattern in my Angular / TypeScript projects. My read-api calls return DTO objects that get state objects injected as well and their properties map directly onto state objects.
These DTOs that end up as untyped javascript objects when they come from the api to the client (Angular) project are then in turn injected as state objects into TypeScript objects, injected in the constructor again and mapped by getters and setters. It works very cleanly and is well maintainable. I have an example on my GitHub (niwra) account (Software-Management repositories), but can expand here if anyone is interested.
MongoDB allows for very clean and Unit-Testable repository implementations, that returns strongly typed aggregates. The only thing I haven't solved cleanly yet is telling MongoDb about state objects for child-collections. Currently that is pretty 'static' still, but I'm sure I'll find some nice solution.
You can store your domain objects as-is in document databases. Vaughn Vernon has posted an article The Ideal Domain-Driven Design Aggregate Store? about this, featuring PostgreSQL new (at that time) JSONB document-like storage.
Of course, you get a risk having your aggregates polluted by BsonX attributes, which you probably do not want. You can avoid this by using convention configuration but you will still need to think about serialisation and this can have an effect on the level of encapsulation.
Another pattern here is to use a separate state object, which is then held as a property inside the aggregate root (or regular entity). I would not call it a "DTO", since this is clearly your aggregate state. You are not transferring anything. Methods inside your aggregate can mutate the state or, even better, the state would be an immutable value object and new state is produced when you need to change the state.
In such case persistence would only care about the state object. You still might be unhappy to have MongoDb attributes on the state object properties and this is reasonable. Then, you would need to have an identical structure inside the persistence mechanism, so you can map properties on-to-one.
A current project needs us to persist domain objects in a NoSQL
database such as mongoDB. In many examples (incl. Eric Evans, Vaughn
Vernon) the domain objects are serialized and persisted to the mongoDB
directly.
I can confirm you that MongoDB is a good choice for persisting DDD models. I use MongoDB as an Event store in my current project. You can use MongoDB even if you are not using Event sourcing, for example using an ODM (Object Document Mapper): you have a document for each Aggregate instance (this applies to any document based database, not only MongoDB) and you store nested entities and value objects as nested documents.
We would like to avoid mixing the domain layer with persistence related inforamtion by not having any annotations in our domain objects.
You can use xml mapping.
Also we are concerned about corrupting the persisted data by changing the domain object in the future.
For this you can use custom migration scripts. If you use Event sourcing then there are event versioning strategies.
We came to the conclusion that we need to have some kind of DTOs translating between the domain objects and the persisted data.
This is a bad conclusion.
If you use CQRS you won't need DTOs because the readmodels are enough.

Using ViewModels instead DTOs as the result of a CQRS query

Reading a SO question, I realized that my Read services could provide some smarter object like ViewModels instead plain DTOs. This makes me reconsider what information should be provided by the objects returned by the Read Services
Before, using just DTOs, my Read Service just made flat view mapping of a database query into hash like structure with minimum normalization and no behavior.
However I tend to think of a ViewModel as something "smarter" that can have generated information not provided by the database, like status icon, calculated values, reformatted values, default values, etc.
I am starting to see that the construction of some ViewModel objects might get more complicated and has potential downsides if I made my generic ReadServiceInterface return ViewModels only:
(1) Should I plan some design restriction for the ViewModels returned by my CQRS? Like making sure that their construction is almost as fast as a plain DTO?
(2) DTOs by nature are easily serialized and ready to be sent to an external system in a SOA architecture or embedded into a message. Does this mean that using ViewModels will have a negative impact on my architecture?
(3) Which type of ViewModels should I keep outside my Read Services?
(4) Should I expect all ViewModels to be retrieved from Read Services?
In the past I implemented some ViewModels that needed more than one query. In a CQRS I suppose, that is a design smell, since everything they provide, should be in only one query.
I am starting a new project, where I thought that any query will return either aggregate objects or DTOs. Since now ViewModels come into play. I am wondering:
(5) Should I plan that queries within my architecture will yield two type of objects (ViewModels+Aggregates) or three (+DTO)?
View Models (VM) serve a single master: the View. We're usually consider the VM a pretty dumb object so in this regard, there's no technical difference between a VM and a DTO, only their purpose and semantics are different.
How you build a VM is an implementation detail. Some VM are pre generated and stored in a VM repository. Others are built in real-time by a service (or a query handler) either by querying the db directly or querying other repos/services then assembling the results. There's no right or wrong and no rules about how to do it. It comes down to preference.
In CQRS the important part is separation of commands from queries i.e more than one model. There's no rule about how many queries you should do or if you should return a view model or dto. As long as you have at least one read model dedicated for queries, it's CQRS.
Don't let technicalities complicate your design. Proper design is more about high level structure and not low level implementation. Use CQRS because having a read model simplifies your app, not for other reasons. Aim for simplification and clean code, not for rigid rules that dictate a 'how to' recipe.

ORM Entities vs. Domain Entities under Entity Framework 6.0

I stumbled upon the following two articles First and Second in which the author states in summary that ORM Entities and Domain Entities shouldn't be mixed up.
I face exactly this problem at the moment as I code with EF 6.0 using the Code First approach. I use the POCO classes as entities in the EF as well as my domain/business objects. But I find myself frequently in the situation where I define a property as public or a navigation property as virtual only because the EF Framework forces me to do so.
I don't know what to take as the bottom line of the two articles? Should I really create for example a CustomerEF class for the entity framework and a CustomerD for my domain. Then create a repository which consumes CustomerD maps it to CustomerEF do some queries and than maps back the received CustomerEF to CustomerD. I thought EF is all about mapping my domain entities to the data.
So please give me some advice. Do I overlook an important thing the EF is able to provide me with? Or is this a problem which can not completely solved by the EF? In the latter case what is a good way to manage this problem?
I agree with the general idea of these posts. An ORM class model is part of a data access layer first and foremost (even if it consists of so-called POCOs). If any conflict of interests arises between persistence and business logic (or any other concern), decisions should always be made in favor of persistence.
However, as software developers we always have to balance between purism and pragmatism. Whether or not to use the persistence model as a domain model depends on a number of factors:
The size/coherence of the development team. When the whole team knows that properties can be public just because of ORM requirements, but should not be set all over the place, it may not be a big deal. If everybody knows (and obeys) that an ID property is not to be used in business logic, having IDs may not be a big deal. A scattered, unexperienced or undisciplined team may need more stringent segregation of code.
The overlap between business logic concerns and persistence concerns. Object oriented design thrives when a class model sticks to SOLID principles. But these principles are not necessarily at odds with persistence concerns. I mean that although the concerns are different, in the end their resultant requirements may be quite similar. For instance, both concerns may require valid object state and correct associations.
There can be use cases, however, in which objects temporarily need to be in a state that absolutely shouldn't be stored. This may be a reason to work with dedicated domain classes. Another reason may be that the entity model just can't fulfill the best segmentation of responsibilities. For instance, a business process "blacklisting customer" may require data that is scattered over so many entity objects that new domain classes must be designed that can encapsulate the data and the methods working on them. In other words: doing this by entities would violate the Tell Don't Ask principle.
The need for layering. For instance, if the data access layer targets different database vendors it may have to consist of interchangeable parts that are vendor-specific (e.g. to account for subtle differences in data types between Oracle and Sql Server or to exploit vendor-specific features). Using the persistence model as domain model would probably bleed vendor-specific implementations into the business logic. That would be really bad. There the data access layer should be precisely that, a layer.
(Very trivial) The amount of data. Creating objects takes time and resources. When "many" objects are involved in a business case it may just be too expensive to build both entity objects and domain objects.
And more, undoubtedly.
So I would always try to be a pragmatist. If entity classes do a decent job, go for it. If the mismatch is too large, create a business domain for appropriate parts of the business logic. I would not slavishly follow a (any) design pattern just because it is a good pattern. Contrary to what is said in the post, it requires a lot of maintenance to map an entity model onto a business model. When you find yourself creating myriads of business classes that are almost identical to entity classes it's time to rethink what you're doing.

Passing DTOs around in the domain model

I see DTO types being created within and passed between types in the domain model. Is this good practise?
I always thought DTOs were to be used principally at context boundaries (i.e. at the edge of the object graph) to decouple context implementations (e.g. at the domain / ui boundary).
Your question is sort of subjective, but that's ok. As with most "hard and fast rules", there really are no hard and fast rules. There are only guidelines. There is always an exception, or some special case where the best course of action is to do something against best practices (like using a goto statement to instantly break out of multiple nested loops).
That being said, no, passing around DTO types withing your domain model is not a good practice. DTO stands for data transfer object, the transfer typically meaning transport across some boundary. If you're staying inside your domain model, you shouldn't be converting to DTO types and then back to domain types.
Creating a DTO hierarchy that parallels your domain model, just for the sake of layering purity, seems like an anti-pattern to me. I'd argue against it every time.
EJB 1.0 encouraged using DTOs this way, because passing entity EJBs that were chatty was inefficient. People would load the data into DTOs to avoid network traffic. I think it's unnecessary now.