I'm following the Controller, Service and Repository pattern and I'm just wondering where DTOs come into this.
Should the controller only receive DTOs? My understanding is you wouldn't want the outside world to know about the underlying domain model?
Should the conversion from domain model to DTO happen in the controller or service layer?
DTOs are most commonly used by the Services layer in an N-Tier application to transfer data between itself and the UI layer. The main benefit here is that it reduces the amount of data that needs to be sent across the wire in distributed applications. They also make great models in the MVC pattern.
The reason you want to use DTOs is that you want clients to couple to that contract, not to your internal data structures. This allows you to modify and evolve your internals freely without breaking clients.
DTO. DTOs (Data Transfer objects) are the objects or classes used to transfer data between layers through the service layer. The service layer only accepts data in the form of DTOs. Any data returned to the controller layer will be in the form of DTOs.
In today programming with Spring MVC and interactive UIs, there are really 4 layers to a web application:
UI Layer (Web Browser, JavaScript)
MVC Controller, i.e. Spring components annotated with @Controller
Service Layer, i.e. Spring components annotated with @Service
Data Access Layer, i.e. Spring components annotated with @Repository
Every time one of these layers interact with the underlying layer, they need to send/receive data, which generally are POJOs, to transfer the data between layers. These POJOs are DTOs, aka Data Transfer Objects.
Only DTOs should be used between layers, and they are not necessarily the same, e.g. the Service Layer may apply business logic to DTOs received from the Data Access Layer, so the DTOs of the Service Layer API is different from the Data Access Layer API. Similarly, the Controller may rearrange the data to prepare it for presentation (grouping, summaries, ...), so the data sent to the web browser is different from the data received from the Service Layer.
With full abstraction, the Data Access Layer's API should not reflect the technology of the Data Access, i.e. whether it is using JDBC, JPA, NoSQL, a web service, or some other means of storing/retrieving the data. This means that Entity classes shouldn't make it outside the Data Access Layer.
Most projects don't need that level of abstraction, so it is common for a DTO to be an Entity class, and to flow all the way from the Data Access Layer to the Controller, where it is used either by a View, or is send to the web browser, encoded as JSON.
It depends on the size and complexity of the project. The bigger the project, the more important it becomes to make each layer as abstract/standalone as possible.
There are different patterns followed by different organizations. It depends on which pattern you follow. From my personal experience, I follow below architecture diagram.
As per the above diagram, DTO to Entity Conversation and vice versa will be inside the service layer only.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With