Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Transfer Object DTO Where to build

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.

like image 696
strash Avatar asked Apr 10 '17 09:04

strash


People also ask

Where do I put DTO objects?

Put the classes close to where they're actually used. Show activity on this post. In your case,the DTO is accessed by both Presentation & Domain. so better to have it Infrastructure and refer it from there.

How do you implement DTO?

In order to implement DTO, let's create a Spring Boot application that exposes REST API. By using that Spring Boot application, we can retrieve the user locations from an H2 database. For implementing that application, we should have knowledge of how to integrate the H2 database with Spring Boot.

Why do we create DTO in Java?

DTO, which stands for Data Transfer Object, is a design pattern conceived to reduce the number of calls when working with remote interfaces. As Martin Fowler defines in his blog, the main reason for using a Data Transfer Object is to batch up what would be multiple remote calls into a single one.

Can DTO have objects?

A DTO may be used to: Flatten object graphs that contain nested objects. Flattened object graphs can be more convenient for clients.


3 Answers

I would say there is no canonically right way to do this. It depends on what is DTO used for.

I found a simple rule for myself on where to use DTO in service level and where to not: In case if service level has only one client I use DTO across service level. In case if there are two or more clients it is better not to use DTO in service level.

Let me explain this in more details:

Basically it is clear that not including DTO into service level requires more efforts. So in case if there is only one client I would keep things simple and use DTO as a return type for service methods.

In case if there are more then one client of the service most likely the clients will require different DTO (for instance I want to have json and csv representation of an object). In such case I will not return DTO from service. Otherwise I would need to have different services for each DTO, or different service methods, etc.

Note: I'm not saying that if you don't use DTO in service level you must move the transformation logic into controller level. I still think that controller level must be as simple as possible. You might have some intermediate transformation level between controller and service - uncomfortable, but it is much better then having several services.

like image 124
Sasha Shpota Avatar answered Oct 07 '22 17:10

Sasha Shpota


I would say it's better to create DTO on Service layer.

Controller must not know business logic details. E.g. we need to return User info but some fields (password etc.) must be excluded. The fields exist in the User entity but must be removed from DTO.

Another case we got SomePaginationDTO on Controller and we still need to pass the DTO to service to parse filter, apply sort, limit results etc. All the logic is part of service responsibility. So I would pass the SomePaginationDTO to service.

like image 30
StanislavL Avatar answered Oct 07 '22 17:10

StanislavL


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.

like image 21
Nicolas Labrot Avatar answered Oct 07 '22 17:10

Nicolas Labrot