C
C#•10mo ago
BElluu

DTO is fine? DTO have any alternatives?

Hello, I read on some blog that DTO should not be used in production. Is it true ? Are there any alternatives to DTO? Having a Product model and ProductDto just because it needs to be trimmed down by a few fields looks pretty dirty. Thank you in advance!
16 Replies
Angius
Angius•10mo ago
Those blogposts are bullshit, then DTOs should be used liberally Data you receive from a request should be a DTO Data you send back should be a DTO
BElluu
BElluuOP•10mo ago
@ZZZZZZZZZZZZZZZZZZZZZZZZZ thank you 🙂 Is there any other approach than DTO?
Angius
Angius•10mo ago
You can do weird stuff like adding [JsonIgnore] attributes to your EF entity properties But it's neither secure nor clean It's best to just use DTOs And if you don't feel like mapping between them and models manually, use something like Riok.Mapperly to map them for you
BElluu
BElluuOP•10mo ago
Thnaks. I do not like stuff like automapper. I will do it manually 🙂 Have a nice day!
D.Mentia
D.Mentia•10mo ago
Thing about dtos is that if some consumer needs more data, you've gotta go modify your api to return it. Where I work, we specifically don't use dtos to try to keep that to a minimum, we use the same db entities for everything. The idea is kinda not knowing or caring about which other services consume your api, return whatever you've got and if someone needs it, it's there Now, to be clear, it's awful for a lot of reasons and I don't suggest it at all but, it is technically an alternative and some reasonably smart people seem to like it for some reason
Angius
Angius•10mo ago
"Hey API, can I get a blogpost?" "Sure, here's the blogpost, the tags, the tag authors and their password hashes and emails, the blogpost author and their password hash and email, here's the category as well, and other blogposts in that category, their authors with their pass—"
D.Mentia
D.Mentia•10mo ago
It's worse than that, here's a blog post, the tags might or might not be null depending on the endpoint, and so might everything on a blog post, arbitrarily with no way to find out which ones are truly null or we just didn't select them POOP at its worst
Patrick
Patrick•10mo ago
it lazy and bad design, I don't think those people are smart in that decision. Savvy, maybe. I would not call on those choices at work to be smart.
D.Mentia
D.Mentia•10mo ago
I didn't say the choices were smart, just that smart people decided they're a good idea, there's a difference. lol And to be fair I think it offers some other advantages that I don't quite understand, which are contingent on other practices we do (that I also don't really agree with but it is what it is)... like for example, if multiple services all deal with the same type of entity, those services share the same entity definition, so we don't have a dozen different Shipment entities. And if an API returns a Shipment entity, you can use it directly in another service without having to map it, and there's no confusion about whether a TrackingNumber it returns is the carrier's tracking number or ours, because it would be returned in the specific property for one or the other, whereas a DTO that returns just 'TrackingNumber' is ambiguous But also we only do that stuff internally, if it's public facing or for clients, DTOs
Patrick
Patrick•10mo ago
I don't know why there would be a distinction to draw
D.Mentia
D.Mentia•10mo ago
I stopped arguing with them about it after a while, but tbh it does help to have me on this side, trying to 'defend' these decisions :lul:
Patrick
Patrick•10mo ago
Services exposing schemas to one another, internal or not, violates SRP and leaks detail coupling individual services to the "right" version of a schema is even worse.
D.Mentia
D.Mentia•10mo ago
I agree, and our databases are often full of a lot of nonsense that we never use or just a bunch of nulls as a result. But it does make sense from the perspective of centralizing business definitions, keeping multiple dev teams in sync and aware of things like that there are two different types of tracking numbers Changing a DTO is already a big deal, and you would already need to coordinate with all of the teams that use it in order to do so, so it's not really any more effort to maintain or change with or without DTOs. But it does get awkward when you want to make an internal change to your db structure, and it's kinda forced to be a public facing change - but, if you're changing something like making this bool into an enum, other teams that use it need to know about that and (eventually) do the same thing But, the more I try to justify it the more it seems clear that it's only possibly beneficial in a very specific situation and very unlikely to be a good idea unless you're working in a big org doing other dumb things that make it worthwhile when you combine them all
Angius
Angius•10mo ago
If you want the client to decide what they need, you use GraphQL Not just say "here's everything, whatever"
D.Mentia
D.Mentia•10mo ago
I think I was wrong about that actually, because we don't really do "here's everything, whatever", we do still specifically select things into it and still generally have to make changes if consumers need new things. I think the advantages are just from the other weird stuff we're doing that some guy decided was a good idea 20 years ago and it's too late to change it all now, and if you happen to have made those same bad decisions, then maybe you don't want DTOs But yeah, TLDR, use DTOs, but technically it is an option to not use them. But I can tell you from experience that it really sucks to not use them Oh, actually now I realize what I was trying to say with that; it's not that you don't have to touch your code if some consumer needs new data (and you're not using DTOs, you're returning db entities from your API) - you do still have to modify the query and include that new data in your output - it's that if you do that, you don't have to change your DTO and mess up all your other consumers Though... most or all deserializiation of your API response is going to ignore any data that isn't in the class they're deserializing to, so even if you updated your DTO, as long as it's just adding a new property instead of modifying one, it's still backwards compatible. So even that isn't really an advantage
BElluu
BElluuOP•10mo ago
Thnak you guys for that discusion 🙂
Want results from more Discord servers?
Add your server