DTO or not to DTO?

DTO or not to DTO?

Thank to the original creator : https://medium.com/javarevisited/dto-or-not-to-dto-58259d4228ec

DTO or not to DTO?

Disclaimer:?This article does not take the existence of the?Java records ?into consideration, and it merely speaks about DTOs, in their classical understanding.

Shall I use DTOs or not?

This is a long-time popular, to some extent debatable, and sometimes, even inclining to so-called “holly war” question, very short answer to which, is

— It depends.

— What is DTO, anyways?

— It is a?Data Transfer Object,?i.e. the data aggregate object, sole purpose of which is to facilitate conveying data from the point A (the source) to the point B (destination).

There are plenty of people, who, in plenty of cases, would prefer one approach (using DTOs) over another (using bare model classes/entities), and vice versa; however, there is no single source of truth?on which is better to use.

It very much depends on the requirements, software design, architectural approach you decide to stick with, other (project-related) specific details, and even on personal preference.

Some even claim that the?DTO is an anti-pattern; some love using them; some think, that data refinement/adjustment should happen on the consumer/client-side (for various reasons, out of which, one can be?No Policy for API changes).

That being said, YES, you can simply return the model class (in?Hibernate , it’s @Entity) instance (or list of instances) right from your controller and?there is no problem?with this approach. I would even say, that this does not even violate anything from?SOLID? or?Clean Code principles .

But again..

it depends on what do you use response for; what representation of data do you need; what should be the capacity and purpose of the object in question, and etc..


DTO is generally a good practice in the following scenarios:

  1. When you want to aggregate the data for your object from different [re]sources, i.e. you want to put some?object transformation?logic between the Persistence Layer and the Business(or Web) Layer:
  2. Imagine you’re using ORM and you have a Java code abstraction for your database. Now imagine, you fetch from your database an?Employee?instance; however, from another 3rd party web service (or just any other source), you also receive some?complementary-to-employee?data for that?employee?object. Say, it’s —?EmployeeContact.
  3. Now, you want to send some data from the?employee?object (let’s say it’s?ID,?Firstname,?Lastname?fields) and some data from the?employeeConcat?object (let’s say it’s?City,?District,?Address?and?PostalCode?fields) to the client, which expects the data, modeling employee and its address, but you do not wish to send these two instances separately (you, especially, will not want to send all the instances separately, if they are more than two).
  4. Instead of sending two instances and delegating assembling responsibility to the client, what you might find as a better and convenient alternative, is to use DTO.
  5. Using DTO would look like creating the corresponding DTO class (let’s say —?EmployeeAddressDTO), that aggregates two (or more) model classes and per each instance of such a class, you will have a model aggregating desired data, which, in the above case , is data from the?employee?and?employeeContact?objects. By the way, during this aggregation, you might also want to do some other things, like data alteration, adjustment, modification, calculation, or etc.
  6. The point is that you want to?combine the data?from different [re]sources and represent that combination as a one, unified object.
  7. This makes a good case to use DTO pattern. DTO is reusable, it conforms to Single-Responsibility Principle, and it is well segregated from other layers.?Note,?that since ;
  8. When you don’t necessarily combine data received from different sources, but you want to modify and customize the model instance, which you will be returning:
  9. Imagine you have a very big Entity (with a lot of fields), and the client, which calls the corresponding endpoint (Front-End application, Mobile, or any client), has no need of receiving this huge entity (or list of entities). If you, despite the client’s requirement, will still be sending the original/unchanged entity, you will end up consuming network bandwidth/load inefficiently (more than enough), performance will be weaker, and generally, you will be just wasting computing resources for no good reason. In this case, you might want to transform your original Entity to the DTO object, which the client needs (only with required fields). Here, you might even want to implement different DTO classes, for one entity, for different consumers/clients, as you might want to?customise?data representation per each client.

Note, that you may have a situation, when your requirements involve both 1st (aggregation) and 2nd (modification/customisation) points mentioned above.

No alt text provided for this image

However, if you are sure, that your table/relation representations (instances of?@Entity classes ) are exactly what the client needs, there is no necessity of introducing DTOs.

Supporting further the idea, that @Entity can be returned to the presentation layer without DTO

  1. Java Persistence with Hibernate, Second Edition , in §3.3.2, even motivates it explicitly, that:


You can reuse persistent classes outside the context of persistence, in unit tests or in the?presentation layer, for example. You can create instances in any runtime environment with the regular Java new operator, preserving testability and reusability;


2. Hibernate entities?do not need to be ?explicitly Serializable.




Per Ghosh

Senior Fullstack developer

1 年

DTOs are horrible but easy to implement and you will se a fast result the first month. A much better approach i to read meta data about fields from database or have some sort och systems where meta data about fields in database are located. Implement one single transfer object for data that are able to dynamically allocate storage for the data it will transfer to or from server/client. A bit more dificullt to implement but you will have one single object used to transfer all data compared to hundreds (if the system is large) of DTOs.

回复
Syed Abdullah

Software Engineer @ Contour Software | .Net core | Microservices | REST APIs | Entity Framework | Sql Server | Flutter

2 年

Thanks for sharing

回复
Soufiane OUNIDA

Software Engineer

2 年

So interesting, thank you Omar

回复
Nabin Ghosh

Java Developer at CGI | Ex-TCS | Java 8 | Spring Boot | Hibernate | Angular 10 | Microservices | AWS | Docker | Jenkins | Devops | VSSUT, Burla, Odisha

2 年

Thanks alot for this post...I was really confused in DTO. This article cleared my confusion.

回复

要查看或添加评论,请登录

社区洞察

其他会员也浏览了