Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is it appropriate to map a DTO back to its Entity counterpart

From what I've read and implemented, DTO is the object that hold a subset of value from a Data model, in most cases these are immutable objects.

What about the case where I need to pass either new value or changes back to the database?

Should I work directly with the data model/actual entity from my DAL in my Presentation layer?

Or should I create a DTO that can be passed from the presentation layer to the business layer then convert it to an entity, then be updated in the DB via an ORM call. Is this writing too much code? I'm assuming that this is needed if the presentation layer has no concept of the data model. If we are going with this approach, should I fetch the object again at the BLL layer before committing the change?

like image 456
aggietech Avatar asked Jan 22 '15 14:01

aggietech


3 Answers

A few thoughts :

  • DTO is a loaded term, but as it stands for Data Transfer Object, I see it more as a purely technical, potentially serializable container to get data through from one point to another, usually across tiers or maybe layers. Inside a layer that deals with business concerns, such as the Domain layer in DDD, these little data structures that circulate tend to be named Value Objects instead, because they have a business meaning and are part of the domain's Ubiquitous Language. There are all sorts of subtle differences between DTO's and Value Objects, such as you usually don't need to compare DTO's, while comparison and equality is an important concern in VO's (two VO's are equal if their encapsulated data is equal).

  • DDD has an emphasis on the idea of rich domain model. That means you usually don't simply map DTO's one-to-one to domain entities, but try to model business actions as intention-revealing methods in your entities. For instance, you wouldn't use setters to modify a User's Street, City and ZipCode but rather call a moveTo(Address newAddress) method instead, Address being a Value Object declared in the Domain layer.

  • DTO's usually don't reach the Domain layer but go through the filter of an Application layer. It can be Controllers or dedicated Application Services. It's Application layer objects that know how to turn DTO's they got from the client, into the correct calls to Domain layer Entities (usually Aggregate Roots loaded from Repositories). Another level of refinement above that is to build tasked-based UIs where the user doesn't send data-centric DTO's but Commands that reflect their end goal.

So, mapping DTO's to Entities is not really the DDD way of doing things, it denotes more of a CRUD-oriented approach.

like image 88
guillaume31 Avatar answered Oct 14 '22 00:10

guillaume31


Should I work directly with the data model/actual entity from my DAL in my Presentation layer?

This is okay for small to medium projects. But when you have a large project with more than 5 developers where different layers are assigned to different teams, then the project benefits from using a DTO to separate the Data Layer from the Presentation Layer.

With a DTO in the middle, any changes in the presentation layer won't affect the data layer (vice versa)

Or should I create a DTO that can be passed from the presentation layer to the business layer then convert it to an entity, then be updated in the DB via an ORM call. Is this writing too much code? I'm assuming that this is needed if the presentation layer has no concept of the data model. If we are going with this approach, should I fetch the object again at the BLL layer before committing the change?

For creating a new entity, then that is the usual way to go (for example "new user"). For updating an existing entity, you don't convert a DTO to an entity, rather you fetch the existing entity, map the new values then initiate an ORM update.

UpdateUser(UserDto userDto)
{
    // Fetch
    User user = userRepository.GetById(userDto.ID);

    // Map
    user.FirstName = userDTO.FirstName;
    user.LastName = userDTO.LastName;

    // ORM Update
    userRepository.Update(user);
    userRepository.Commit();
}

For large projects with many developers, the disadvantage of writing too much code is minimal compared to the huge advantage of decoupling it provides.

See my post about Why use a DTO

like image 41
Yorro Avatar answered Oct 14 '22 02:10

Yorro


My opinion is that DTOs represent the contracts (or messages, if you will) that form the basis for interaction between an Aggregate Root and the outside world. They are defined in the domain, and the AR needs to be able to both handle incoming instances and provide outgoing instances. (Note that in most cases, the DTO instances will be either provided by the AR or handled by the AR, but not both, because having one DTO that flows both ways is usually a violation of separation of concerns.)

At the same time, the AR is responsible for providing the business logic through which the data contained in the DTOs are processed. The presentation layer (or any other actor including the data access layer, for that matter) is free to put whatever gibberish it wants into a DTO and request that the AR process it, and the AR must be able to interpret the contents of the DTO as gibberish and raise an exception.

Because of this requirement, it is never appropriate to simply map a DTO back to its Entity counterpart.

The DTO must always be processed through the logic in the AR in order to affect changes in the Entity that may bring it to the state described by the DTO.

like image 29
Matt Mills Avatar answered Oct 14 '22 00:10

Matt Mills