Data Transfer Object DTO Where to build

strash picture strash · Apr 10, 2017 · Viewed 7.9k times · Source

Trying to refactor some code. I see some classes creating DTO objects which are being passes in the service layer and returned later by the @RestController. As I know it is best to build the Data Transfer Objects only in the controllers and pass them to the views, especially when we use something like WrapperDTO<T> with get and set value. Maybe there are differences when we are building the WrapperDTO with complex object or simple data types. All oppinions will be well appreciated.

Answer

Nicolas Labrot picture Nicolas Labrot · Apr 10, 2017

DTO may be used to transfert data between the different layers of an application: DAO, Service, Facade, Controller. In my experience DTO is an opinionated topic.

In my opinion, the later the conversion, the better, it is even better if no conversion is needed. Generally, the later is at the application boundary. DTO is not free, it involves mapping and its support. Hence DTOs will make sense when there is a domain model mismatch or a model technical mismatch accross the boundary. For more information you can have a look at LocalDTO article and the associated link.

If I focus on the service -> facade -> controller layers:

  • Services: They are doing services things and they may call each other to do their processing. If your domain models remain consistent across the services boundary service => facade it is too early to convert the result into a DTO.

  • Facades: They may orchestrate services and convert input/output. In my point of view it will be the right place to convert to or from DTO. But only if it is needed to ie. because your domain models have to be transformed accross this boundary (filtering fields, aggregation...)

  • Gateway/Controllers: They are at the application boundary. Their logics are simple, reduced to the boundary logic. The relation between a facade and a controller is usually one <-> one. ***

    Merging facades and controllers usually make sense


Thus in my point of view, your first proposal is more adapted eg. UserController..... The most important is to stay pragmatic.