81

I am learning about DDD so apologies if my question is naive. I think I need to use Local Data Transfer Object in order to display data to the users as a lot of properties are not part of any of Entity / Value Objects.

However, I am not sure where this DTO should be implemented - in a Domain Layer or in an Application Service Layer. The DTO implementation seems part of the Domain, but it means that when I create a collection of DTOs in the Service Layer and pass it to a Presentation Layer, I have to reference Domain Layer in Presentation Layer, which seems wrong.

What is the correct way to implement DTO using DDD principles?

JGFMK
  • 8,425
  • 4
  • 58
  • 92
user2105030
  • 831
  • 1
  • 7
  • 7
  • 5
    Why are you under the impression that a DTO is part of the Domain? A DTO is a technical representation that is serializable friendly. – plalx Jul 16 '15 at 04:13
  • As far as I know it is part of Data Layer. Domain Layer includes use cases, repository (not the implementation), and the models (domain model). Data Layer on the other hand includes repository (implementation), data source which includes DTO and Entity. – Bitwise DEVS Feb 26 '22 at 18:08

5 Answers5

61

Define the DTO to the layer where the source of the values comes from.

Relative to OP's question: place the DTO in the Application Service Layer. DTO is an output of that layer, it makes sense if you define it there. Don't put your DTO in the Domain Layer. The Domain Layer does not care about mapping things to serve external layers (the domain does not know there is a world outside of its own).

Presentation Layer (closes to consumers)

  • This could be your API
  • Has Models or Dto definitions of its own with attributes relative to its layer. If this is an API then Models/DTO have attributes for formatting or data type validations
  • This is the "Application Root" (meaning that it must reference both Domain Service layer, Data/Infrastructure Layer to be able to inject services)
  • Maps data between ApplicationService.Dto and Presentation.Dto

Application Service Layer

  • Has Dto definitions of its own to be able to return data without exposing the domain entities.
  • Bridge between Presentation Layer and Domain Layer.
  • Contains Application Services. See answer https://stackoverflow.com/a/3840552/1027250 for detailed definition of Application Services.

Domain Layer

  • Domain entities
  • May contain Interfaces bridging the infrastructure layer, defined in words that can be understood by the business, free from technical terms (IE: IExcelReport, IGoogleSheetReport, IRepository)
  • May contain "Domain Services"

Data / Infrastructure Layer (closest to your database or external services)

  • Database infrastructure (mapping).
  • Excel libraries if you define this layer as infrastructure code.
  • Mail or notification services.
  • PDF output files
Pang
  • 9,564
  • 146
  • 81
  • 122
Yorro
  • 11,445
  • 4
  • 37
  • 47
  • 1
    nice answer... I assume by Service Layer you mean Domain Service Layer - would be good to clarify so it does not get confused with Application Service Layer. – Hooman Bahreini Sep 28 '18 at 09:09
  • 1
    @Hooman - Yes a Domain Service Layer. I think the DDD world have move on from "Service Layer" to "Domain"Service Layer. I think it makes a lot more sense to call it specifically a domain service layer nowadays because of the other service layers appearing lately. – Yorro Sep 28 '18 at 12:07
  • 12
    Even Domain Services are part of domain, It should go to application service layer. – Code Name Jack Apr 21 '19 at 14:56
  • 1
    I think you meant "Application" layer, no? – Vinicius Dias Oct 09 '19 at 06:15
  • 6
    A Domain Service has nothing to do with an Application Service – Gabriel Oct 23 '19 at 16:24
  • 10
    I think this answer is creating confusion between Application Services and Domain Services, and between the Application Layer and the Domain Layer. – Timo Oct 24 '19 at 08:58
  • I think this answer is not correct. It should be in the application service layer. – XRaycat Apr 01 '20 at 09:58
  • Domain Service Layer is known as Application Service Layer? The fuck. In the multiple layers ( Presentation, Domain, Application, Core, Infrastructure) or in Onion layer also Persistence. Please just call it "Application layer" where the DTO is returned and not "Domain Service Layer". Lol – NicoJuicy Jul 25 '20 at 23:40
  • 10
    **There is no Domain Service Layer** in DDD. DDD has *domain services* that naturally belong to the *domain layer*. In some situations when the domain service needs to interact with other BCs or external systems, then the domain service *interface* is created in the domain layer, and the domain service *implementation* is created in the infrastructure layer. See the discussion around Listing 17-6 in Millett & Tune's book. – Paulo Merson Aug 18 '20 at 21:43
  • 1
    @PauloMerson you are right. I have renamed the "Domain Service Layer" – Yorro May 12 '21 at 05:48
  • Sorry for the confusion. I have renamed the layers to avoid confusion. – Yorro May 12 '21 at 06:06
31

Such DTOs that are exposed to the outside world become part of a contract. Depending on their form, a good place for them is either the Application Layer or the Presentation Layer.

If the DTOs are only for presentation purposes, then the Presentation Layer is a good choice.

If they are part of an API, be it for input or output, that is an Application Layer concern. The Application Layer is what connects your domain model to the outside world.

As an interesting observation, it follows that the Presentation Layer should access the domain model only through the Application Layer. Otherwise, we lose our single point of access - we'd have multiple layers invoking the domain model. The Application Layer exposes all of our use cases. Whether they are invoked by a call from another service or by the Presentation Layer makes little difference.

Sources

The core of these concepts I learned from The Red Book by Vaughn Vernon. (I would quote from it, but I don't have it handy.) The chapters about the Application Layer and the Presentation Layer are relevant.

Primarily, my conclusions come from being strict with the concepts as presented by Eric Evans and Vaughn Vernon, and prioritizing freedom in the domain model, as this is Domain-Driven Design:

  • The domain model should be easy to change. That means not exposing domain objects externally, as having external dependants would make them hard to change (without breaking things).
  • The Application Layer is the external point of access. It is what defines the use cases on the domain model. That means not operating on the domain model from elsewhere. The Presentation Layer can only go through the Application Layer. Nobody likes having to deal with many different points of access!
Timo
  • 7,992
  • 4
  • 49
  • 67
  • This sounds like a reasonable answer. IMHO, application layer makes sense, as it's a boundary of application, and therefore in/out go only DTO(s). Can you please add some references and/or studies, articles, backing statements in the answer? – kravemir Nov 01 '19 at 18:47
  • 2
    @kravemir I agree with you. I would add that the Presentation Layer, in turn, could simply borrow the DTOs from the Application Layer, as they are part of a contract (and thus change-resistent) anyway. Alternatively, the Presentation Layer may have reasons to prefer DTOs of its own, such as when a radically different shape makes more sense to build the view. The price, of course, is additional translation. So I would start with piggybacking on the Application Layer's DTOs, and diverge as the need arises. – Timo Nov 02 '19 at 12:48
16

Yorro is right about where to place DTO but I encourage you to avoid "DTO mindset". This way of thinking collides with DDD way of thinking.

Thinking about "I need a DTO here" is thinking about technical representation (as plalx says); it is a level of abstraction too low. Try a higer level of abtraction and think about your domain, user's tasks and your UI.

Do you need get view data to the user? Bring it to UI through a View Service that return a specific YourViewInfo class.

Do you need to send data to some Service to perform a task? Send it a specific TaskMessageInfo class or a specific Command class.

When you begin to modeling the internals of these classes is when you should start to thinking about its technical representation; then you could reach to the conclusion that could be, i.e., DTO classes for convenience.

Thinking this way helps you to model the system and doesn't trigger questions like

Where to put or belongs this thing?

jlvaquero
  • 8,571
  • 1
  • 29
  • 45
  • 2
    Is your point simply using a different name? YourViewInfo instead of YourViewDTO? – Markus Pscheidt Jan 25 '17 at 09:13
  • 2
    @MarkusPscheidt No. My point is that in a domain contextualized architecture (DDD) DTO does not mean nothing so you can not ask about where are they placed. You could talk about DTOs if you are generalizing concepts to explain something but, in your architecture, you should not model DTOs; you model the context and the context is wich determines where is placed the model. My point is that the question has no sense in a DDD world. – jlvaquero Jan 25 '17 at 12:03
14

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.
Take a look at the following articles to go deeper with DTO and layering:

FireAlkazar
  • 1,795
  • 1
  • 14
  • 27
1

Hexagonal (Ports/Adapters) Architecture

What has to be mentioned here is so-called Hexagonal (Ports/Adapters) Architecture [Vernon, the red book p. 125]. It is very convenient to place objects that represent data for the external (outside the domain & the application) comsumers. The architecture is the great addition to Layered Architecture generally implied by DDD.

Here is the example.

Along with ports/adapters for a DBs, email services etc.

We may define a ports/adapters/http/ui/myestore/ShoppingCartResponse.valueobject.ext (assume we use some imaginary programming language EXT) that contains the data your UI application MyEStore will use to show the end user his shopping cart state.

ShoppingCartResponse.valueobject.ext is created by ports/adapters/http/ui/myestore/EStoreHTTP.adapter.ext (for brevity it could be a synonim for a very slim HTTP REST API controller from REST world in our example).

The adapter asks the domain service ShoppingCart.service.ext for aggregates, entities, other value objects. Then it creates the desired ShoppingCartResponse.valueobject.ext from them (by itself or with creators - factories, builders etc.). Then sends the value object as an HTTP response to the consumer.

DTO or Value Object?

Whether ShoppingCartResponse would be a value object or a DTO (.dto.ext) you should decide based on

  • The particular structure of your Ports/Adapters object hierarchy;
  • If it is justified to have another type of object, a DTO, in the system, or it is better to keep only value objects only;
  • A semantic meaning of DTO vs value objects in object hierarchy;
  • The responsibilities differentiation between them: say your value object would do some invariants logic-keeping, whereas DTO could be just a dumb object with no logic.

I would prefer starting with the simplest approach, allowing only for value objects, and add DTOs only as the clear architectural need in them appears.

This approach gives much flexibilty yet it keeps code design clean and simple. Ports/Adapters section accommodates objects that belong together (the adapter, VO or DTO, their creators) and keeps Application Layer clean keeping the space for more relevant application layer objects.

Valentine Shi
  • 6,604
  • 4
  • 46
  • 46