ASP.NET 6 REST API Following CLEAN ARCHITECTURE & DDD Tutorial | Part 1 - Project Setup

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone welcome to my brand new series building a rest api completely from scratch following clean architecture and domain driven design principles let's get started in this series we're going to be building a web api completely from scratch and i'm going to try to make the videos more or less self-contained so in this video we're not going to be diving too deep we're going to be talking a bit about the product that we're going to be building the back end for what's the idea behind it and then we'll set up the project following clean architecture we'll connect some stuff together we'll start setting up a bit of authentication and each video will dive deeper into understanding the different methodologies i don't think it's possible to remember everything in a single video that's why i'll talk about it when we'll be implementing it so we'll keep going back to the outer picture and then in to the specific thing that we're going to be implementing in that video so what is this it's basically a dinner hosting platform and it goes by the same concept of uber where you take your car and you turn it into a taxi or airbnb where you take your home and you turn it into a hotel so here you can take your home and turn it into a restaurant if you're familiar with the main driven design you may be looking at this and already starting to look for aggregates for domain models how you would structure this what will the model look like and if you're not then you might be thinking to yourself what the heck is an aggregate but what i want to do is just for you to look at this and start imagining what what's the data that we have here and how things might look like behind the scenes right so we have here maybe a title a description starts and end time we have a array of pictures and some other stuff here i just want you to get your mind imagining how you might architect this yourself but we will get into this later on just for now i want you to get the idea of what we're going to be um reaching in the end great so this is the product that we're going to be building now if you've already heard of clean architecture or you're familiar with clean architecture then you definitely saw such a diagram or something that looks similar to this it's sometimes called clean architecture onion architecture ports and adapters hexagonal architecture and even though they have different names it's variations of the same core concept where you have your domain in the center of everything your core logic your core application is in the center and infrastructure details like the database or web clients and so on sits on the outside and that's for you to be able to replace it without having to change your core logic of your application this is specifically jason taylor's clean architecture model you'll see many variations but the concept the core concept is the same so even though this is what you'll usually see for me it's easier to imagine it this way so this is what we're going to be working with throughout the series but if you look at it one actually the other you'll see it's the same right so in both of them you have the presentation in the infrastructure taking a dependency on the application right so same over here and in the core or in the bottom you have your domain if you're curious then you can pause the video and take a look what what's inside every layer but i really don't want you to try to remember what's over here i want us to develop an intuition you have a deep understanding of what goes where so you don't need to remember anything you'll just know intuitively or you'll have a deep understanding of what needs to sit in which layer so we're going to use libraries like mapster mediator fluent validation decrypt error or and we're going to be covering many common concepts and design patterns such as cqrs repository unit of work and of course the architecture of the project is going to be following clean architecture and domain-driven design principles and we'll be using visual studio code so many.net developers aren't familiar with these tools so i'm sure you'll find some pretty interesting things that i hope you'll be able to add to your toolkit and of course we'll use cli for everything so we'll be covering some interesting commands if this seems interesting then make sure to subscribe and follow along hopefully by the end of the series then you'll have a deep understanding of these technologies and you'll have a good intuition as to how to logically split your applications even if it's completely different so i do have a couple of disclaimers first and foremost this is an educational video we're going to be covering a lot of topics mainly so you get to know them and maybe you can use them in your application if it's applicable but don't take everything that you see as face value and edit your application it's probably overkill for many many scenarios so that's first of all second of all this is so opinionated there's so many different approaches to many of the stuff that i'm going to show so this is just what i decided to go with in the end if you have maybe a different approach or you just want to comment and let me know what you think and how maybe you would have done it then please drop a comment this isn't for a complete beginner so if you don't know rest you don't know what a web api is or if you just feel like it's going way way way too fast then this might not be for you and i apologize and that's it my opinions keep changing all the time so please feel free to educate me as well this is a series that i've been wanting to do for a really long time i would have loved to have a video like this when i started learning these topics and if you aren't already following me on linkedin and on twitter so i create a lot of nerdy visual infographics that you might enjoy so take a look if you're into those kind of stuff if you really want to understand clean architecture domain-driven design and how to use all these libraries that we're going to be covering then i highly highly recommend you follow along it's not enough to just watch the videos so if you haven't already go ahead and download visual studio code in the dotnet sdk and let's get started so what are we going to be doing today today we're going to be creating the solution setting up the projects the dependencies between the projects and we'll start doing some authentication work that we'll continue in the next video we'll also get to know visual studio code and the development environment that we're going to be working with so the first thing we want to do is create the solution so that new sln and let's give it the name uber dinner this created the folder booper dinner which inside has the journal solution now let's go ahead and create the projects so the first one we're going to be creating is the booberdinner.api project so i hope this isn't too small to see but the presentation layer has two projects inside one of them is going to be the web api which will be listening for requests and the other one is going to be the contracts which will model our api so let's go ahead and create the web api project so dot net new web api and let's give it the name uber dinner dot api next let's create the contracts as we said this will model our um api so let's call this contracts now out i'll zoom in here out of all the five projects that we have this is the only one that's actually a web api and they'll be listening for requests all the other ones are just class libraries okay next let's create the infrastructure project so infrastructure application and lastly the domain so let's see what we have so we have our five projects and the solution now let's build it and see what happens and we see that we get unable to find a project to restore which seems odd right because we just created five projects but if you haven't worked with the.net cli then you wouldn't be familiar with this where if we look at the solution file so we can see it's still empty we need to actually add the projects to the solution so let's do that dotnet sln add and we here we want to say all the various cs projects so we can get it recursively like this great so now let's build it build and it builds successfully now let's create the dependencies between the projects so we have the api project they pre the api project needs to know about sorry needs to know about the contracts project and about the application project so let's go ahead and do that so dotnet add first we say which project and we want to add a reference to the contract and the application layer perfect next you want the infrastructure to have a dependency on the application crate and the application of a dependency on the domain so now that we have that set up you might be asking yourself how is this possible right so if the only project that's a web api is the uber dinner dot api then how will we be able to use the infrastructure project if it's not reachable so if we look at it like a tree then the infrastructure layer is unreachable right so if we look at the dependencies we can't reach the infrastructure layer and the truth is that theoretically the infrastructure layer is independent from the presentation layer but in actuality we do need a project reference between the api layer and the infrastructure layer because we want the infrastructure layer to be able to register its own dependencies so we'll look into that later as we go on so for now let's add the dependent the the infrastructure as a dependency to the api project i'm going to do the other way around let's learn api and infrastructure so now that we have everything set up let's open this in visual studio code so let's take a look at what we have we have our solution with reference to the five projects that we created we have the api project which is the only one that is using the web sdk we're using.net six and we have here a reference to the three projects where the domain is accessible via the application so the api has reference to all the projects essentially let's look what else we got here so we have the application layer which should have a dependency only on the domain we have the contracts which doesn't have a dependency on anyone same goes for the domain and the infrastructure has a dependency only on the application so let's go ahead and build our solution great and it built successfully so the next thing i want to do is um show you a the tool that we'll be using to make the http requests throughout the series so if you go to the extensions and you look for rest client and you'll find this extension which has 2 2 million downloads and a higher rating than 4 seasons so it's pretty impressive and this is what we're going to be using to make the requests you can take a look at their documentation which is great but we'll also take a look now at some of the basic features so we created the web api from the template so what we get with the template is a single controller the weather forecast controller which is available under the host slash weather forecast all right because of this trick over here and um what it returns is five random forecasts so let's make a request to the to the endpoint and see that it works as we would expect so dotnet run then we need to specify the project the product that we want to run is the api project and now let's go ahead and make a request using the rest client extension so let's create a new folder let's call it requests inside here create a folder weather and the file get forecast a plural forecasts right not cs and http okay and the way this works is you basically just write the url that you want to query and you can see right away it pops out this send request option let's take the route to the endpoint so that will be the host which is over here flash weather forecast let's copy this paste it over here and click send request i mapped it to shift enters i just click shift enter and we get five random forecasts let's do it again we see that it's random great so now that we have everything set up what i want to do is get rid of everything that isn't necessary for us to start i want to have the minimum code as possible so let's get rid of this weather forecast model this controller and in the program cs let's get rid of all this all of this and this and if this looks weird to you and you're used to seeing a program cs and a startup cs so this is the new web api template starting from.net six where you basically have a single file where you can define everything so over here you have the builder.services or the builder in general which you can use it to for configurations and the dependency injection and over here you have your regular um request pipeline configurations so a nice trick that i saw is just creating a scope and putting it inside i like it it just seems more organized okay the next thing we want to do is over here get rid of this we won't be needing that and fix this put this underneath i think it was also in the infrastructure layer all right fix this and let's get rid of all these empty classes perfect let's build a project see that it still works the dotnet builds perfect everything seems good i'll go back to the diagram i want to look that's what we'll be creating so we basically have the register endpoint and the login endpoint so here's the how the request will look so you basically have the first name the last name a unique email and the password and then the response you get everything back other than the password including an id and a token and for logging in you only need the email and the password and your response looks actually exactly the same right so this and this are modeled in the same way so these are our two endpoints and the requests as you would expect right so they arrive at the authentication controller they'll be you they'll be using either the login or the register request model the request will then go to the authentication service which is sitting in the application layer over here at the moment we're just going to return a mocked response so just a hard hard-coded values which will go back to the controller and this will go back to the client like that so what's the rationale behind splitting the code logically between the presentation and application layer so we want the presentation layer to be the door to the outside world so currently we're using rest but we'd want to have the option when we're modding modeling it to replace this with graphql or grpc or some other technology that will come up in the future so the idea here is that this is a gateway to the outer world we want to take the data that's coming in take it from that form and transform it to the language that our core logic of the application knows to speak and that's the la that's the language that's in the domain layer and application layer which has our use cases so in this case one of our use cases in our application is the user being able to log in and the user being able to register so that's why it sits in the application layer so i just want to note that in the final result we're going to be using cqrs and mediator and this won't look like this but just for the moment this is what we're going to be using so let's go ahead and implement it so the first thing i want to do actually is to create your new folder i'll call it docs inside here let's just call this api dot markdown and i'll paste in the api definition so let's paste it in here so this is the api definition that we looked at before visualized let's open it in this markdown preview extension it's called markdown preview enhanced you can use it it's great and this is just so we have it when we're modeling our request so let's go to our contract and over here let's create a new folder authentication authentication looks right over here let's create the register request and the login request and let's also create our m authentication response right so instead of the same model for both of them so authentication response great go ahead and model it so we have a register request register request which has a first name a last name an email thank you give up copilot and a password pick and for the login it will be exactly the same so copy the namespace but it'll be only the email and the password this will be login and for the response so as we said it's going to look similar to this let's copy everything here only it's going to be authentication response it's not going to have the password this instead will be the token and over here we're going to have the id that was generated right so this models this thing over here great so now that we have that let's go ahead and create our controller so we're in the api controllers let's create a new authentication controller a public class authentication controller this will inherit from the controller base let's give it the api controller attribute which does the magic behind the scenes we'll get into it maybe in the future if not then i'll create a video about it in the future but this does a couple of things behind the scenes and let's set the route right so i could do controller but this would match authentication and over here i think i wrote here robot let's just write off like that and we want two endpoints right the register and the login let's go ahead and do that so route register amazing and return action result call it register yes that's what i wanted thank you kids co-pilot and login i can write it perfect and this won't be the register request will be the login request and that seems about right let's return the request from here and from here as well so let's run the project and see that it's working as we expect so let's run the api and i just noticed that i wrote your route and i meant to write http post so let's run the project see that everything is wired together as we expect it to be over here let's delete the weather instead let's create an authentication folder which will have register and login over here let's copy the url and instead of host let's put our actual host which is over here and we need our body so if we try to make a request then this will fail and that's because we haven't defined anywhere that we're sending json so let's do that content type content type application json make the request and we get the response as we expect and something that you can do with the rest client plugin is create variables so we can say okay i have the host variable which is this now i can replace this with host right so now it matches the definition of the api we can just copy and paste this and it should work and if you want to add multiple requests in the same file so simply put three hashtags and then you can define all the requests here so we've got another request then and we can send it as well and there's still so common so you can add your title if you prefer but for me i find it easier to just separate different files that way i can search for the request that i want to make and then call it so this is for a register let's copy it to the login which will be the same only login and it will need only the email and the password and we get the stack great so in the future we'll see how we can take these variables and define them as environment variables and that way we don't need to have them defined in each of the files right so we'd have for example the token we'll set the token value and then it'll work throughout all of our requests but the usage will still be the same with the same syntax okay so let's go back to our controller and over here what we want to do is send it to the authentication service in the application layer so let's close some stuff here go to the application layer create services inside authentication and here we'll have the authentication service dot cs let's have this interface and let's copy and paste this and tap implementation as well authentication yes that's what i want but as we said before we don't want the definition of our api to leak into the application layer because then it's harder to version it in the future and change the schema of the requests so we don't want to have anything from the contract project in the application layer now luckily we can't because application layer doesn't reference up towards the api or the contracts so even if we wanted to we can't this is just an example of how separating the projects like this and defining the dependencies it stops us from doing something that might not be aligned with what we want to do logically so instead let's have this receive for now let's have it just get the values right so we have the first name first name the last name the email and the password perfect and for the response so the response for both of them both of the methods will be the same right so we said this receives only the email and the password but the response from the service will be the same so let's just create an object for the responses call it authentication result and this will consist of a this yes right let's see that i'm not missing anything right so we have the id the first name the last name the email that's open right so that's how this is the response now don't worry we're going to be refactoring this multiple times in the upcoming videos so for now and just bear with me this will be result right both here and here and let's implement this namespace public class authentication service which implements the eye authentication service and let's let's implement the two methods for now let's just return a new authentication result let's have it see what what it's offering yeah why not right so it's generating a new guide and for the token just hard codes token let's wrap this and let's do the same over here just the tier we don't have the first name and the last name so let's just have it for now hard coded strings obviously in the next videos we'll replace this with the actual implementation and great so now that we have this defined application layer we can go back to the controller and use it so private i application service yes that thing authentication service let's inject it to the control constructor then we can call it from here so let's say bar results equals and let's call the authentication service register let's pass it all the details so not just this request dot first name make sure that it's what we want email and password yes it seems right let's wrap the argument and see what it wants so it doesn't have an overload takes four arguments and that's because yeah i messed up the names here so this should be registered this should be login and now that we have a result then we can map the values to the api response which is the authentication response so let's create that response new authentication response yes that and here we can just have it result dot id all right it's the guide the first name the last name the email and the token perfect and let's have it return the response and for the login it's going to be more or less the same so let's go ahead and copy all this paste it over here instead of calling register let's call login and get rid of this map it exactly the same and return our response right so let's try calling our backend and see if it works oh i updated the names in the interface but i didn't update it in the forum invasion so let's replace these two right so this is login and this one is register and let's try again great so it's running and now i'm going to make the request and some of you might already be saying this ain't going to work and if that's what you're thinking then you are right and that's because we implemented the interface but we didn't define anywhere how to inject it right because the controller is requesting the interface and that's the exception that we're getting so let's go to our program cs add the the dependency so let's add it as it's scoped we want the authentication service to be the authentication service perfect so now that we have this wired up let's run the project again go to the register request make a request and as we expect it works so here we have a random guide and we have the hard-coded token let's check the login requests and then goes for the login only that here we have these two strings hard-coded as well so now that we have all of these stuff set up there's one other thing that i want to talk about in this video so in our clean architecture structured solution we want each layer to be in charge of its own dependencies so what we did until now is we registered the authentication service over here in the program cs but it's actually defined in the application layer and it would be nice if we can just say to the application layer listen i want you to register all of your dependencies and same goes for the infrastructure layer and then if you have separate teams for example then each team knows where to look for its dependencies so in many teams when the project becomes big you might have an entire team that works only on the infrastructure layer for example i know in microsoft it's like that in many teams so let's go ahead and do that so we want to create a new file just close everything in the application layer let's call it dependency injection what we're going to have here is a single static extension method that registers everything that's him for the application layer so public static and class the pen empty injection let's have this the public static and here we want this service collection add application right and this will be i service collection services and over here we'll do all our registrations now we could try to add it but it's not recognized and that's because this is just a class library if you're like me and you don't remember what symbol belongs to which nougat package then there's another visual studio extension which i like which is called reverse say something nougat reverse yes this thing nuget reverse package search basically what it allows you to do is select a symbol and then reverse search and it'll tell you which package it belongs to so let's try doing that ctrl shift p reverse package search and here it is so this is the package that we want to use so let's go ahead and add this so net add to the application layer the package microsoft extensions dependency injection self-abstractions great now we can add it and let's move the definition from the program cs to here let's include this we can now get rid of this using statement over there and we need to return the services now we just need to call it from over here so let's say builder dot add application services dot add application so we're calling it from here let's do the same thing for the infrastructure layer so let's just actually copy this file paste it over here in the infrastructure layer and we want to change some stuff here let's update this to infrastructure let's get rid of this and this and of course we want to call this ad infrastructure structure let's call this from the program cs as well so add application and add infrastructure let's make a request and see that this still works so dotnet build nice let's run it so we have our register with request seems to work let's log in and it works as well that's it for this video thank you so much for joining me i had a great time making this this is actually my first ever youtube video so i'm very eager to hear what you thought about it so please let me know in the comments that's my best way to improve last thing before we finish i want to show you a sneak peek of what's coming up in the next video so what we currently have and let me zoom in is we have the authentication controller which makes a call to the application layer right now for us it's authentication service this is part of the final result diagram and what we're going to be doing in the next video is implementing a jwt token generator which from the point of view of the application layer it's just making a call using the interface so it's going to return a response it's going to go back to the user but the actual implementation is sitting over here in the infrastructure layer so we're going to be creating both a jwt token generator and the password hasher this is a good example of separation of concerns between the layers so that's why i wanted to add authentication to the service even though probably in companies like uber and probably in your company as well you have some identity server which will be in charge of this stuff but it's a good way to look at how to separate your logic between the different layers i'm really enjoying making this series and it's taking me much more time than i would have thought it would take so if you're liking this and you want to support my channel make sure to subscribe hit a like and my source code will be available for my patreons but if you don't want to don't worry you can still follow along using only the videos i want to thank milan and paul for taking the time to sit with me and go over the architecture gave me some great insights so thank you for taking the time and see you in the next one
Info
Channel: Amichai Mantinband
Views: 235,849
Rating: undefined out of 5
Keywords: Dotnet, Clean Architecture, Domain Driven Design, DDD, C#
Id: fhM0V2N1GpY
Channel Id: undefined
Length: 37min 45sec (2265 seconds)
Published: Mon Jun 06 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.