Domain Driven Design (DDD) in Golang!?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
domain driven design as this how I use it is to ensure a service speaks the language of your domain so like the language of your service right um so you we need to get this email and this username and we need to ensure it speaks the language of our service and um and that's exactly what this pattern tries to solve right so I have a domain folder which has my domains in there and I have a package in here called user so firstly what we're going to just create in this package is the user a domain so this would be a struct um this would be what's called like your aggregate root so it would store object value types um which all speak the language of your domain right so we would have an ID in here and we' then have another type called user ID or in this case just ID um so you'd have ID as an ID um uh what else did we have we had a email so again you'd have a type down here called email email and this would be the email type uh and then you would have the other name which was username as a string right so we just drop that in here so I'll keep this simple obviously you can structure this into different files and make it nice and easy right so the idea is simply is you would have a method on here called new so now we've got our new um Factory method here what we're going to do is actually return a new user aggregate rout right right so we would have ID it would be um our ID type we're going to use the just to keep the simple uh. new [Music] string uh from Google and we have our email and now we're going to take in an email type here because we've already at this point would have initialized our object value types so we would have a you know username as a username and uh email and we can populate username as our username right so what follows on from that is we would have new ID and this would return a um ID and any error and this would then take in your primitive value so you would have ID and that would be as a string this time or we call it I um in this case so what we' return is obviously you know we're going to return that as the value type but this is where your domain logic comes in right um so what you would have here is you could say we're having a new ID and we want to validate that someone's like say um we had a method that actually took in an ID we wanted to validate that it speaks the language of our domain what you would have in here is like for example the uid package you know where you could then pass the ID and we would have you know valid ID at this point and any error so we can then check the error of this uh passing um you know and then you can define domain errors so you could have like you know error invalid ID errors. new uh and invalid ID provided something like that um and then that means you can then do something like errors do um you know errors uh you could do fm. error F you could rrap the error for example so you would have like this um now screw it even better one the new method errors. join right so we would have the error and then we could have error in valid ID um you know but this is essentially like your domain rules right so any rule you may have like you might have a rule for example to have like the length of the ID must be greater than 10 right and then you can define an error here to say it's not 10 um that sort of thing right um and then we've got the B ID here so we just pass in oh actually in that case if it's valid we can just you know we know it's valid we got it and we can return it um but what you then have again is to get it back to A Primitive type you would have I as an ID and you return it as a string so in this case here you would return string I um and what we do is we'll just very quickly implement this for the other two types right so as you can see now what we've got is we've got an aggregate rout so this is our user domain and we've got the object value types of the user of domain so these types basically speak the language of the domain right so the idea is any code that needs to you know speak the language of your application so the domain um needs to use the factory methods to new up its um primitive type say from like an adapter in the ports an adapter pattern or say you just you just have like a struct of request object and you want to get that into your like you want to have that all validated and have that into your application it would go through all of these object value types and then you would know that all of the uh all the types basically speak the same language as your domain right so to to make sense of that we have a service here which was the dummy service I mentioned at the start of the video um what we would do is take the username um that I'm passing in here and we would use user. new username and we would pass in uh the username and of course we have errors right so this is where you know you can check errors and then straight away we know if this is an invalid username we can just return the error right and you can do special logic like if the error is because you what you would essentially have right is in your domain you would have like VAR error name or error name too long right or something like this and you could then you know write the logic for that return the error um and then you could obviously come into your application and you could you know do um and errors you know like just just special logic is what I'm getting out here right so you could do you know user error name too long so if the if the name is not too long then skip it like this is your this is your domain now having logic tied to it that you can use throughout um services or business logic if you like um so I'll tell you what I'm just going to remove that here we go and what I'm going to do now is just new up the final we one which was the email so I'll just call this um user email so we don't get naming complex and we'll have user. new email we'll take in the email address and we will return the error again I should really bind the if not equal to n to a key because that obviously as you know as a go developer is all you type all day every day um anyway so we've now got two fields which are valid object value types in our business logic so uh what we would now do is take these two fields and come down here and we would use the user. new user because at this point we have all of the valid object value types of a user right so we can now pass in a user uh name and um what was it user email uh so I make sure I do a little typo in here uh username user email oh okay I've got the wrong way around that makes sense uh like that right so now we have a valid user so we can now call this user an error uh there's not an error here because we already know everything's valid um but at this point we have a user which is completely valid and um is a valid like user domain type in our application right so at this point onwards we could could um you know use this for our business logic we could um pass to repositories pass to the database and we know it's valid data going to it and so on right so I'm going to do another video to kind of talk about how this ties in to like a wider broader pattern with like datase adapters and that kind of thing and that would be on What's called the ports and adapters pattern also known as like the hexagonal architecture pattern um but just to finish up here we're going to extend this just to return a oh we already have the food response type here so that would actually be you know obviously sign up response um so we'll return that and the error and this is this is kind of the reason for the um for the output right tell you what I'll do I'll just return a point to it so we can return nil here nil here and then we can come down here so what you can now do is obviously we want to return a response and we want an ID and as you know we have uh U do ID do string right because we now can get that back to A Primitive type so what we've got just to go over this one more time is we've got a a dto right which is a data transfer object um which holds primitive Fields right so these are just fields that are like transmittable over the wire like a you might have an adapter like a HTTP adapter so this would be HTTP request object which are just going to be strings because obviously that's all that Json can store or it' be like an integer or a Boolean or date time right basically just normal everyday types uh that your service method would then take in that request and it would um obviously I'm not actually using that type I just noticed but think of it as that type here um I can't really you know trying to save time here but uh think of that of that type here and then as you can see we're then changing the two Fields so username into the user domain and we would validate any business log or any not business logic but domain logic so data validation right we make sure um the username isn't too long or it's not empty or it hasn't got like you know Bad characters in it that we don't support in a system that kind of thing um we' then have the exact same thing for an email address so we'd validate it actual email and then finally we get to our aggregate root user type and we can just pass in our object value type into that um which at that point you can return back to Primitives so essentially um you know we want to get uh request fields to speak our domain language um but that's pretty much it I hope obviously it made some type of sense this tutorial um is a little bit all over the place but again this will make a bit more of um sense when it gets to the hexagonal architecture videos and the ports and adapters videos um and just as a disclaimer this is probably an opinionated view on how to do domain driven design go I'm sure there's loads of other ways to do it and I'm sure you've probably seen better or if not different ways of doing it and by all means hit me in the comments with any um suggestions of how you think I could improve this domain package um like I say this is just kind of how I've done things and what's worked for me and and businesses I've worked in um so uh yeah leave a like if you if this has helped you guys and um catch you data run
Info
Channel: samvcodes
Views: 19,327
Rating: undefined out of 5
Keywords: ddd pattern in golang, domain design design go
Id: 6FY9urgIjqo
Channel Id: undefined
Length: 11min 30sec (690 seconds)
Published: Sat Sep 16 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.