Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JHipster VMs vs DTOs

Tags:

dto

jhipster

i would like to understand a bit more about the decision of JHipster's option of generating DTOs. I've got several questions about it.

  1. Why is it called DTO? It is described in the release notes of JHipster 3.6.0, that it can be used to execute business logic on these objects. If this is actually the intention of it, then it is not only a DTO (Data Transfer Object). It is more, it is in my opinion a Domain Object. Ok, perhaps this is also not an ideal term, as Domain Object is also interpreted as a parent term for DTOs, entities, etc. From a DDD perspective it might also be called Aggregate, as it combines multiple Domain Objects.

  2. Based on 1., i think, that the current scaffolding of DTOs doesn't fit well to the intention of DTOs combining multiple entities. In that case it wouldn't be related to one specific entity and therefore shouldn't be generated in the context of that entity.

  3. I think the current scaffolding of DTOs fits much better to the JHipster's definition of VMs (View Models). If you have a complex entity with a lot of relations and perhaps also some blob or clob data, you don't want to submit all that data to the frontend. You need a VM to cut off dependent objects, that are not needed by the UI. This fits well to the current DTO scaffolding, as relations are only represented by IDs. This is also what is still described on the JHipster website for DTOs. I think this description is deprecated and fits well for VMs, but not for DTOs anymore. Here is the quote from the JHipster website:

Those objects add an extra layer on top of the domain objects, and are specifically tuned for the REST layer

Has the concept of DTOs and VMs not been thought through completely, or am i missing some important aspects?

like image 774
Stefan Tomm Avatar asked Dec 01 '16 10:12

Stefan Tomm


People also ask

Are DTOs outdated?

Although DTO is not an outdated pattern, it is often applied needlessly, which might make it appear outdated.

Are DTOs good practice?

DTO is generally a good practice in the following scenarios: 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.

Are models DTOs?

Data Transfer Objects (DTOs) and View Models (VMs) are not the same concept! The main difference is that while VMs can encapsulate behaviour, DTOs do not. The purpose of a DTO is the transfer of data from one part of an application to another.

What is the difference between entity and DTO?

An Entity is defined only for the purpose of storing it in a database. It is, simply, a Java representation of a table in a database. A DTO, on the other hand, is the class we use for all operations other than database-related ones.


1 Answers

Although I cannot say why the decision was made by the team, I absolutely agree that the DTO/VM-concept is not very clear.

I think, the basic idea was in analogy to the MVP/MVC pattern where often a new view-model is introduced to get a MVVM pattern. So the DTOs that do not affect any view were "pushed" into the actual model/controller layer. Which is ok, if you say that a DTO is a transfer-object between the services.

However, we also had "trouble" and a lot of discussions with the layers and the DTO, VM and so on in our older jhipster-app. We started at the same time when jhipster introduced the DTOs and Mapstruct stuff. In new projects, where we use Jhipster, we always remove all DTOs and VMs. First of all: the (Managed)UserVM/DTO stuff, which is very confusing. This has several reasons:

We never have a VM in the server-side of our applications. In a jhipster application, where the view is entirely based on javascript/angular, the view model must be there. We often have other applications that uses the REST-API and these applications are not views. So, especially in a microservice-architecture, I never would call something in a REST-API "view" or even "view-model". Thus, in such applications where no view is written in Java (with JSP or so), you will never find the term "VM" in our Java code. Furthermore, there might be different kind of views (e.g. the angular web-app, an iOS app, a desktop client or other things) and each of them has other views, view parts, widgets and therefore needs other view-models. Finally, there were some people that say that the REST-API may not provide any stuff that is not a real resource/entity...

So, you are absolutely right that VMs in jhipster are in fact DTOs. But, as you also say, there is a problem with "DTO", because normally a DTO is just a stateless transfer object to encapsulate common values between two or more services (or systems) without any logic. We think that this is also a architectural problem between the top-down (REST) API-driven and bottom-up domain-driven design, which are somehow mixed in JHipster apps. Similar to your opinion, I think that JHipster uses DTOs where it should be a domain object (or an entity). E.g. a managed user is not a VM or a DTO, it is an entity. I think, the problem here is that some people think that only JPA-based entities are domain objects and there could be no other domain objects (entities).

Finally, we decide to introduce a new type called ADO (API Data Object or Access Data Object), because we found no term that fits. An ADO is compared to jhipster a VM, a DTO or even an entity without any logic. A common "API-Layer" only reads and writes ADOs. This layer is used for the REST API controllers as well as for a Java API that can be used by plugins. This gives us the possibility to ship all ADOs with the client-API-jar without adding any specific internal entities or domain objects. Since the REST-API and each plugin use the same ADOs (and therefore the same description and structure), the developers are not confused and the outer resource-oriented layers are properly separated from the internal layers that use another business logic than only resource-based.

Everything else that is part of the internal layer like entities, derived entities, subsets or supersets of entities are mostly domain objects. So we consequently removed all VMs and DTOs from this internal layer, the business logic and so on.

In sum: To encapsulate the internal (JPA) entities from the external access, we use the ADOs, since there might be others than just views. These ADOs are in terms of jhipster VMs as well as DTOs. But internally behind the common API layer, we never use any DTO or VM or even an ADO, because those entities are mostly domain objects.

like image 183
Indivon Avatar answered Sep 19 '22 23:09

Indivon