Why use DTOs (Data Transfer Objects)?

Поделиться
HTML-код
  • Опубликовано: 11 янв 2025

Комментарии • 47

  • @micahlhoover
    @micahlhoover 3 года назад +27

    The big justification for DTO's here is "avoid changing contracts". I've worked on several enterprise apps where DTO's are everywhere (DTO between service and controller, between controller and front end type script, between inbound front end and what can be accessed from the HTML, and even in the same layer the DTO's have DTO's). People ask, "Why do we have three of the exact same classes?". How do you decide when it is best to have a DTO?

    • @CodeOpinion
      @CodeOpinion  3 года назад +15

      I generally have DTO's for any exchange between boundaries. Those could be integration boundaries or service boundaries. Integration boundary would be between say a web framework and my application.

  • @andysmason
    @andysmason 3 года назад +1

    Awesome. I am implementing this in JPA similarly (same concept) and I was so confused on the loading of a whole tree structure and then having to prevent children loading parents who in turn load the children..... and then you are stuck in a loop. The data that I am working with is not hierarchical either, so this makes so much more sense to control the outer facing endpoints with constant data. This helps a lot. Thank you, Derek.

  • @xxapoloxx
    @xxapoloxx 4 года назад +6

    But this is really not a good reason to use DTOs, I will need an ever increasing amount of DTOs to contend to every possible variation on the client server, while simultaneously either ignoring or having to create an ever increasing amount of business logic to contend with all those DTOs.
    It would be more reasonable to implement a method on the logic class that returns only the required information of the class instead of all of it.

  • @ReyAlexam
    @ReyAlexam 3 года назад +2

    I still didn't get the full idea of it. I mean if we change the backend the client has to do some modifications as well regardless of whether thay are using DTO or not

    • @CodeOpinion
      @CodeOpinion  3 года назад +2

      Don't necessarily need to change the client if something changes in backend. If you have multiple clients consuming the same API then you're going to want those contracts to be relatively stable.

    • @wasiaamir8125
      @wasiaamir8125 3 года назад

      ruclips.net/video/9pSIc9TstIk/видео.html

    • @ToeShimmel
      @ToeShimmel 2 года назад

      Using a contract DTO gives you more flexibility as well. For instance when exposing multiple API versions. You can have one DB but expose different DTO's per version. At least in most cases I guess.

  • @sangmin7648
    @sangmin7648 2 года назад +1

    Should the controller and the service get different dto as an argument? Or is it ok for controller to pass down the request dto to the service?

  • @aliamini6890
    @aliamini6890 3 года назад +3

    Awesome, so there is no difference between ViewModel and DTO? if there is could you please explain it a little

    • @CodeOpinion
      @CodeOpinion  3 года назад +5

      Often ViewModel for some people means having behavior specific to the view along with data. While DTO is purely data without behavior that's generally serialized.

    • @Sergio_Loureiro
      @Sergio_Loureiro 2 года назад

      Normally DTOs are dumb objects, which are only made of data fields; and at most their only intelligence is made of methods for serialize or deserialize.

  • @FatMooseHenry
    @FatMooseHenry 3 года назад +1

    I use DTO's and also have a domain layer and a data layer. Often these classes are very alike. How do you handle mapping? I have gone away from automapping and is instead using a constructor which takes all properties of a class. If I add a property to my datalayer, I much perfer to get a compiler error everywhere the property is not set/initialized. With auto mapping/reflection etc, it will either not be set or an exception will happen at runtime. Any compile time mappers available or how do you handle that?

    • @CodeOpinion
      @CodeOpinion  3 года назад +2

      I don't auto map generally and map manually. Generally DTOs are used for Messages (Commands, Queries, Events) and for Query Results (ViewModels)

    • @Adiu72
      @Adiu72 Год назад

      I hate automapping. I saw a lot of errors, unused properties and a lot of mess because of this. It is so easy then to left something uninitialised or remove from one class and leave in another. I choose manual mapping to better control what can be null and what cannot. Then I will receive an error that this non nullable property is not assigned etc. Additionally you are adding DTOs to be able to rename a variable for example. With auto mapping you are creating a bug then because now this property will not be mapped to the old name in DTO.

  • @ivandrofly
    @ivandrofly Год назад +2

    @CodeOpinion What are difference between DTOs, Models and Entities? I would really appreciate if you make a video on it

    • @uksame
      @uksame 4 месяца назад

      Models/Entities are the same which used for defining you Data base tables entity => data base tables, hence for the data base context. on the other hand DTO as the name implies between the server side to the client side and vice versa. since both have a similar construction but still they differ that DTO is used to control which Data you need to columns or parameters you wanna deal with without over exposing unnecessary data to the client and for minimizing the bandwidth ..., etc

  • @iancarr3923
    @iancarr3923 4 года назад +3

    I liked the brevity and clarity in the presentation.

    • @CodeOpinion
      @CodeOpinion  4 года назад

      Thanks for the feedback. I appreciate it.

  • @peymannaji
    @peymannaji 3 года назад

    In my opinion, DTO is reflection of database model + logic. I don't even expose my Dto's to clients and its job is transfering data between the layers of applications and not to the clients. Instead of exposing DTO's to the client I use envelops which is a flat object without any logic. It can be similar to DTO but envelopes are exactly what you what to represent to the clients. Some people think that introducing envelopes is over killing but in my opinions is a best practice to not expose data structure to the clients.

    • @CodeOpinion
      @CodeOpinion  3 года назад +1

      From P of EAA: martinfowler.com/eaaCatalog/dataTransferObject.html

    • @peymannaji
      @peymannaji 3 года назад

      @@CodeOpinion Thanks for the link, so different ideas/thoughts ...

    • @peymannaji
      @peymannaji 3 года назад

      @@CodeOpinion He says:
      The solution is to create a Data Transfer Object that can hold all the data for the call. It needs to be serializable to go across the connection....
      I agree completely with the first sentence.
      But disagree if whole DTO should be serialized. Necessary we don't need to serialize whole DTO. Maybe I just need to pick just some specific properties. And not serializing whole DTO which is more expensive. I've experienced such as scenario a lot.

  • @MsTArray
    @MsTArray 2 года назад

    so contract DTOs never change? the problem I see here for instance is different boundaries using different terms for the same thing, like you said customer vs buyer, wouldn't this become a miss if abused?

    • @CodeOpinion
      @CodeOpinion  2 года назад +1

      They do/can change but at a different cadence or concern than internals.

  • @user-rp9iis1en6h
    @user-rp9iis1en6h 2 года назад

    Where to put business logics, inside DTO or inside entity?

    • @CodeOpinion
      @CodeOpinion  2 года назад

      Check out: ruclips.net/video/PrJIMTZsbDw/видео.html

  • @kylegivler8372
    @kylegivler8372 Год назад

    Great explanation. thanks for sharing

  • @kissthecoder
    @kissthecoder 2 года назад

    Great video! However I'm still a little confused on how you would expose information to the client that isn't already included in the dto representation. Assuming you have a separate buyer record and you wanted to expose the buyerId and buyerName in the order's json representation, would it be better to read the buyer record, include as part of the order model, and map directly to the viewModel as in the video or read the buyer record in the handle() method and populate the dto that way? I feel the second approach would cause code duplication if I wanted to include the same values in the html representation. However, the buyer information in the order model belongs to the buyer aggregate root.

    • @seanharricharan7602
      @seanharricharan7602 2 года назад

      I assume it's because in the DTO, there could be aliases to hide columns name, schemas etc in the backend to prevent injection attacks etc.

  • @heathbaron2277
    @heathbaron2277 3 года назад

    Should people use the DTO postfix?

    • @CodeOpinion
      @CodeOpinion  3 года назад +1

      suffix you mean? Like CustomerDTO? Doesn't matter to me, just be consistent.

  • @jameshickey84
    @jameshickey84 4 года назад +2

    Agree, I think the same goes even for internal classes, for example. Let's say I have object A and B. B accepts A as a dependency and adds some extra functionality, computes values or whatever.
    However, A has dependencies on other things (via an interface, etc.) like data access, IO, etc. How do I now test B without requiring all that data access?
    Well (a) mock everything needed by A and pass A to B.
    or
    (b) Make B accept a DTO instead of A directly. Now, testing B is much simpler and has no dependencies on A or it's transitive dependencies.
    This is like what Michael Feathers calls a "seam" I believe?
    Thoughts? (I'm sure you have some 😉)

    • @CodeOpinion
      @CodeOpinion  4 года назад

      Do you mean passing in data objects rather than behavior objects that have side effects? eg, making pure functions?

    • @jameshickey84
      @jameshickey84 4 года назад

      @@CodeOpinion Yes, but the issue is not that the "behavior objects" are causing side effects at the exact time you use them. It's that the consuming class has to now depend on all those additional dependencies to be mocked or faked in order to test the consuming class. Make more sense?

    • @keithnicholas
      @keithnicholas 4 года назад +1

      Hard to tell from an abstract example, But generally you do this by decoupling A from B, the most common way is make B accept an interface that A implements rather than make B directly depend on A. There are other ways and other problems that might be happening in this situation, for instance it might have to do with the design of A having too many dependencies, both A and B might need to be broken apart into more fine grained objects.

    • @jameshickey84
      @jameshickey84 4 года назад

      @@keithnicholas Yup, def. If using an event-driven design, then something like I said is pretty common too. That "DTO" would be a message or an event, for example. Even if we are doing that in-memory, for example. But agree, interface is the first thing to try when decoupling two classes. In some cases, you may not want the interface as the "message" or DTO being passed between them might be stored somewhere, serialized, or just don't want to implement an interface when all you need are a few fields. 👍

  • @heymanchan9007
    @heymanchan9007 2 года назад

    Well explained , thank you👏👍

  • @ahmadmayahi
    @ahmadmayahi 4 года назад +6

    TL;DW - 04:30

  • @habibm19
    @habibm19 4 года назад

    Great articulation.

  • @ThoughtsInVideo
    @ThoughtsInVideo 3 года назад +1

    I think this obliterates the joy of programming

  • @musegandavlog187
    @musegandavlog187 4 года назад

    Nice content,thanks for sharing...

  • @gafarolanipekun1202
    @gafarolanipekun1202 3 года назад

    Great stuff

  • @JosifovGjorgi
    @JosifovGjorgi 3 года назад +1

    DTO aren't objects, they are modified (in structure and nomenclature) of your data from database/persistent storage.
    Easy way to implement is with objects. A better approach is with serializer/deserializer from specific framework, but that is more work, but it will save you from naming things nightmare.
    Like, orders in
    context 1 - Order DTO 1 or OrderContext1
    context 2 - Order DTO 2 or OrderContext2
    etc...
    Good naming can give you ability to recognize if something is really an object or not