6

I'm building a web application with Spring, and I'm at the point where I have an Entity, a Repository, a RestController, and I can access endpoints in my browser.

I'm now trying to return JSON data to the browser, and I'm seeing all of this stuff about DTOs in various guides.

Do I really need a DTO? Can't I just put the serialization logic on the entity itself?

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
Blaine Lafreniere
  • 3,451
  • 6
  • 33
  • 55

4 Answers4

6

I think, this is a little bit debatable question, where the short answer would be:

It depends.


Little longer answer

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

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

Some even claim that 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 @Entity instance (or list of entities) right from your controller and there is no problem with this approach. I would even say, that this does not necessarily violate something from SOLID or Clean Code principles.again, it depends on what do you use a 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 resources, i.e. you want to put some object transformation logic between the Persistence Layer and the Business(or Web) Layer:

    Imagine you fetch from your database a List<Employee>; however, from another 3rd party web-service, you also receive some complementary-to-employee data for each Employee object, which you have to aggregate in the Employee objects (aggregate, or do some calculation, or etc. point is that you want to combine the data from different resources). This is a good case when you might want to use DTO pattern. It is reusable, it conforms to Single-Responsibility Principle, and it is well segregated from other layers;

  2. When you don't necessarily combine data received from different sources, but you want to modify the entity which you will be returning:

    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.

However, if you are sure, that your table/relation representations (instances of @Entity classes) are exactly what the client needs, I see 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;

  3. You might also want to have a look at this question.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
  • Thank you for your response. I think it worth mentioning that with a framework like spring boot one can easily reuse domain entites and hides some fields to the client with Jackson library annotations. Something like @JsonProperty(access = Access.WRITE_ONLY) on the fields to exclude when serializing to JSON – daniel rubambura Sep 25 '22 at 11:47
1

In general, it’s up to you to decide. If your application is relatively simple and you don’t expose any sensitive information, an response is y ambiguous for the client, there is nothing criminal in returning back the whole entity. If your client expect a small slice of entity, eg only 2-3 fields from 30 fields entity, then it make sense to do the translation or consider different protocol such as GraphQL.

Michel Milezzi
  • 10,087
  • 3
  • 21
  • 36
  • So we should always select all columns for a table (resource) from the database in REST API? I am not from software engineer field. What I want to ask is we can do SELECT ABC, DEF from TABLE A right? – CloudWave Feb 28 '22 at 05:14
0

It is ideal design where you should not expose the entity.

It is a good design to convert your entity to DTO before you pass the same to web layer.

These days RestJpacontrollers are also available.

But again it all varies from application to application which one to use.

If your application does a need only read only operation then make sense to use RestJpacontrollers and can use entity at web layer.

In other case where application modifies data frequently then in that case better option to opt DTO and use it at the UI layer.

Another case is of multiple requests are required to bring data for a particular task. In the same case data to be brought can be combined in a DTO so that only one request can bring all the required data.

We can use data of multiple entities data into one DTO. This DTO can be used for the front end or in the rest API.

Abhijit Bashetti
  • 8,518
  • 7
  • 35
  • 47
0

Do I really need a DTO? Can't I just put the serialization logic on the entity itself?

I'd say you don't, but it is better to use them, according to SOLID principles, namely single responsibility one. Entities are ORM should be used to interact with database, not being serialized and passed to the other layers.

jwpol
  • 1,188
  • 10
  • 22