Pass DTO to service layer
Asked Answered
M

3

15

Is it not bad practice to pass DTO object to service layer?

For now my service layer method look like this:

public save(MyEntity entity);

Mapping values from DTO to business entity (MyEntity) is done on presentation layer

But I want to change method signature to this:

public save(MyEntityDTO dto, String author);

And after it mapping from DTO to business entity will occur on service layer.

EDIT: I want it because I need opened hibernate session when mapping from DTO to business object, so all changes on entity will be automatically flushed.

Mencius answered 20/11, 2013 at 9:48 Comment(1)
its not crime, it all depends, read some articals about Software Layered Architecture ...Pentheus
A
18

Is it not bad practice to pass DTO object to service layer?

Not only you could pass DTO objects to Service Layer, but you should pass DTO objects instead of Business Entities to Service Layer.

Your service should receive DTOs, map them to business entities and send them to the repository. It should also retrieve business entities from the repository, map them to DTOs and return the DTOs as reponses. So your business entities never get out from the business layer, only the DTOs do.

See the full answer to a similar question here.

Avlona answered 15/10, 2015 at 18:9 Comment(6)
this is how I always thought about it. However in certain examples I've seen online (namely in the case of REST API servers) the service layer accepts DTOs but returns Models with I find rather perturbing (eg. Client add(ClientDTO client)). Any idea what could be the rationale here ? Cheers!Wingo
I know I'm a bit late to this, but what if I'm calling a service from another service?Haunting
Wrong answer. Bottom layers should not know about layers on the top of your architecture. They should have their own api to provide the ability to communicate between each other inside layer. For communication between services you will use only service layer objects without any mapping to controller (client) level dtos. For communication between controller and service you have to do some basic validations and mapping to service layer objects and then call actual service methods.Thirza
This answer is so wrong, that it shows how SO can be misleading and it must not be considered to be only valid developer resource at all costs and in all cases. It is WRONG. Service layer should not have any idea about your DTOs, it is a business layer and it should only deal with business. In controller you should deal with DTOs.Muimuir
However maybe it would be wise to define what is your DTO object? To be it is an object on presentation layer, thus REST controller. Just imagine you are changing something in REST layer... why should I change the service/business layer as well? Did business logic change somehow? No, probably just change in the mapper entity -> DTO and that mapping is done in controller.Muimuir
@Thirza The answer author has 34k reputation, and I see similar answer all around stackoverflow, for instance https://mcmap.net/q/365036/-how-to-properly-convert-domain-entities-to-dtos-while-considering-scalability-amp-testability.Eulogist
S
7

It's debatable. (As evidenced in comments to the accepted answer) On the one hand, DTOs are belong to the layer of the application that deals with Data Transfer, which is your presentation layer apparently.

On the other hand, your domain object (business entity), which is properly dealt with in the service layer, probably has properties in it - like, say an Id, a LastUpdated or such that are not passed into the save method. So what do you pass in? Well, you pass in just the properties you need. And it just so happens, that the request MyEntityDTO for save() will happen to encapsulate all and only those properties!...

So you now have the unfortunate choice between:

  1. Passing in the business object from the presentation layer

    (Breaks the layering model too, and forces you to ignore properties like Id and LastUpdated, which are not in the "request")

  2. Breaking up the DTO into properties and passing them in:

    service.save(Dto.Property_One, Dto.Property_Two)

    which you then have to put back together in the save() method.

  3. Creating some new object to encapsulate Property_One, Property_Two etc

  4. Accepting that the DTO is for transferring between layers too

None of these is ideal imo, which is why I think #4 is okay. Probably the most correct is #2 - but again.. not ideal.

Sometimes naming my ease the pain: "MyEntityRequest" instead of "DTO"

Skald answered 7/12, 2021 at 13:19 Comment(1)
If the service layer returns entities i guess we have another problem regarding transactions. If the entity returned by the serivce has some lazy collection ,we should open the transaction in the Controller to acces the data right? Is ok to open the transaction from the controller?Ectropion
M
0

It's ok, all standard 3 layer architectures do that. Dataaccess gets the data, business maps and manipulates it, presentation presents it. It is not ok - but, as said no crime - to pass dataaccess models to presentation - to this point u should pass business models. Btw. "DTO" can mean anything, business layer models can be DTO's, data access model can be DTO's. DTO's are usually POCO's in C#. Usually you have your dataaccess models, representing your database entities and your domain models wich pass the data around your application. The domain models are usually DTO's (or call it POCO). That means, in Microsoft speech, they are completly serializable, so you can pass them to any microsoft .net component. You can serialize them also to xml, json and so on ...

Manure answered 20/11, 2013 at 10:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.