Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should services always return DTOs, or can they also return domain models?

People also ask

When should DTOs be used?

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.

Should you always use a DTO?

A really simple rule of thumb is that you should only use a DTO object when you need to ... transfer data. That means use a DTO at the boundaries in your web API, or when you are sending the object on a message bus. Internally, just use your domain objects.

Are DTOs part of domain?

DTO and Domain are different layers. So it requires mapping from one to another and usually it is done in what is called Application Services layer.

Should repositories return DTOs?

Short answer: No. Long answer: repository is responsible for turning persisted data back to entities (models) and vice versa. Model is a business Model representing a business entity.


it doesn't feel right when domain model leaves business layer (service layer)

Makes you feel like you are pulling the guts out right? According to Martin Fowler: the Service Layer defines the application's boundery, it encapsulates the domain. In other words it protects the domain.

Sometimes service needs to return data object that wasn't defined in the domain

Can you provide an example of this data object?

If we should strictly stick to DTOs, should they be defined in service layer?

Yes, because the response is part of your service layer. If it is defined "somewhere else" then the service layer needs to reference that "somewhere else", adding a new layer to your lasagna.

is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer?

A DTO is a response/request object, it makes sense if you use it for communication. If you use domain models in your presentation layer (MVC-Controllers/View, WebForms, ConsoleApp), then the presentation layer is tightly coupled to your domain, any changes in the domain requires you to change your controllers.

it seems it wouldn't make much sense to create DTO that is the same as domain model)

This is one of the disadvantage of DTO to new eyes. Right now, you are thinking duplication of code, but as your project expands then it would make much more sense, specially in a team environment where different teams are assigned to different layers.

DTO might add additional complexity to your application, but so are your layers. DTO is an expensive feature of your system, they don't come free.

Why use a DTO

This article provides both advantage and disadvantage of using a DTO, http://guntherpopp.blogspot.com/2010/09/to-dto-or-not-to-dto.html

Summary as follows:

When to Use

  • For large projects.
  • Project lifetime is 10 years and above.
  • Strategic, mission critical application.
  • Large teams (more than 5)
  • Developers are distributed geographically.
  • The domain and presentation are different.
  • Reduce overhead data exchanges (the original purpose of DTO)

When not to Use

  • Small to mid size project (5 members max)
  • Project lifetime is 2 years or so.
  • No separate team for GUI, backend, etc.

Arguments Against DTO

  • Duplication of code.
  • Cost of development time, debugging. (use DTO generation tools http://entitiestodtos.codeplex.com/)
  • You must synchronize both models all the time. (personally, I like this because it helps know the ripple effect of the change)
  • Cost of developement: Additional mapping is necessary. (use auto mappers like https://github.com/AutoMapper/AutoMapper)
  • Why are data transfer objects (DTOs) an anti-pattern?

Arguments With DTO

  • Without DTO, the presentation and the domain is tightly coupled. (This is ok for small projects.)
  • Interface/API stability
  • May provide optimization for the presentation layer by returning a DTO containing only those attributes that are absolutely required. Using linq-projection, you don't have to pull an entire entity.
  • To reduce development cost, use code-generating tools

I'm late to this party, but this is such a common, and important, question that I felt compelled to respond.

By "services" do you mean the "Application Layer" described by Evan's in the blue book? I'll assume you do, in which case the answer is that they should not return DTOs. I suggest reading chapter 4 in the blue book, titled "Isolating the Domain".

In that chapter, Evans says the following about the layers:

Partition a complex program into layers. Develop a design within each layer that is cohesive and that depends only on the layers below.

There is good reason for this. If you use the concept of partial order as a measure of software complexity then having a layer depend on a layer above it increases complexity, which decreases maintainability.

Applying this to your question, DTOs are really an adapter that is a concern of the User Interface / Presentation layer. Remember that remote/cross-process communication is exactly the purpose of a DTO (it's worth noting that in that post Fowler also argues against DTOs being part of a service layer, although he isn't necessarily talking DDD language).

If your application layer depends on those DTOs, it is depending on a layer above itself and your complexity increases. I can guarantee that this will increase the difficulty of maintaining your software.

For example, what if your system interfaces with several other systems or client types, each requiring their own DTO? How do you know which DTO a method of your application service should return? How would you even solve that problem if your language of choice doesn't allow overloading a method (service method, in this case) based on return type? And even if you figure out a way, why violate your Application Layer to support a Presentation layer concern?

In practical terms, this is a step down a road that will end in a spaghetti architecture. I've seen this kind of devolution and its results in my own experience.

Where I currently work, services in our Application Layer return domain objects. We don't consider this a problem since the Interface (i.e. UI/Presentation) layer is depending on the Domain layer, which is below it. Also, this dependency is minimized to a "reference only" type of dependency because:

a) the Interface Layer is only able to access these Domain objects as read-only return values obtained by calls to the Application layer

b) methods on services in the Application Layer accept as input only "raw" input (data values) or object parameters (to reduce parameter count where necessary) defined in that layer. Specifically, application services never accept Domain objects as input.

The Interface Layer uses mapping techniques defined within the Interface Layer itself to map from Domain objects to DTOs. Again, this keeps DTOs focused on being adapters that are controlled by the Interface Layer.


In my experience you should do what's practical. "The best design is the simplest design that works" - Einstein. With that is mind...

if we strictly use view models, is it ok to return domain models all the way to controllers, or should we always use DTOs for communication with service layer?

Absolutely it's ok! If you have Domain Entities, DTO's and View Models then including database tables you have all the fields in the application repeated in 4 places. I've worked on large projects where Domain Entities and View Models worked just fine. The only expception to this is if the application is distributed and the service layer resides on another server in which case DTOs are required to send across the wire for serialization reasons.

If so, is it ok to adjust domain models based on what services need? (Frankly I don't think so, since services should consume what domain has.)

Generally I'd agree and say no because the Domain model is typically a reflection of the business logic and doesn't usually get shaped by the consumer of that logic.

If we should strictly stick to DTOs, should they be defined in service layer? (I think so.)

If you decide to use them I'd agree and say yes the Service layer is the perfect place as it's returning the DTOs at the end of the day.

Good luck!


It seems that your application is big and complex enough as you have decided to go through DDD approach. Don't return your poco entities or so called domain entities and value objects in you service layer. If you want to do this then delete your service layer because you don't need it anymore! View Model or Data transfer objects should live in Service layer because they should map to domain model members and vice versa. So why do you need to have DTO? In complex application with lots of scenarios you should separate the concerns of domain and you presentation views, a domain model could be divided into several DTO and also several Domain models could be collapsed into a DTO. So it's better to create your DTO in layered architecture even it would be the same as your model.

Should we always use DTOs for communication with service layer? Yes, you have to return DTO by your service layer as you have talk to your repository in service layer with domain model members and map them to DTO and return to the MVC controller and vice versa.

Is it ok to adjust domain models based on what services need? A service just talks to repository and domain methods and domain services, you should solve the business in your domain based on your needs and it's not the service task to tell the domain what is needed.

If we should strictly stick to DTOs, should they be defined in service layer? Yes try to have DTO or ViewModel just in service later because they should be mapped to domain members in service layer and it's not a good idea to places DTO in controllers of your application(try to use Request Response pattern in your Service layer), cheers!