ASP.NET Core Full Course For Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to this beginner level course where you will learn how to build a complete web application step by step using ESPN net core and the C language my name is hula Cal and I spent the last decade building all sorts of cloud-based applications that handle millions of requests every month by the end of this course you will have master all the skills necessary to start your journey into C backend development even if you have never created a web application before so let's get started by taking a quick look at the application that you will build across this curse imagine that your team has been asked to build a game catalog section of your company's video game store the frontend developers already took care of building the web UI for this game catalog where administrators can manage the information about all the games offered by the store now you as the backend developer need to figure out a way to stand up the back end that will provide all the game data required by the front end the game data lives in a relational database with tables for games and game generous and to let the front end access all these data you will create a new res API that will provide all the standard operations to create list update and delete games in this course you will create this backend from scratch using the latest Innovations in Asad net core and C if you're interested on the front endend portion of this system please check out my blazer tutorial link to this video where I cover how to build that part in detail now creating an hn net cord backend involves understanding multiple Concepts techniques and patterns that I'll cover in detail in this course you will start by learning how to create run and debok your first spnc application from scratch then we go over the Core Concepts behind rest apis and how to quickly implement the traditional grow endpoints in an hnet core API as you implement your res API you will also explore the use of data transfer objects or dto to define the contract between your API and the front end then you'll see how to use extension methods and Route groups to properly organize your API endpoints you will also spend some time trying out invalid inputs to learn how to ensure they are properly handled by your API next you will introduce real database support via the popular Entity framework core or framework which is included with the net platform this will also be a good time to explore the hnet core configuration system which will help you avoid hardcoding important configuration details in your C code next you will explore in detail the dependency injection design pattern and how service lifetimes work in ESPN code applications you will also learn here how to properly map your entities to DTS to ensure you maintain the data contract with your front end while keeping a flexible data model you will complete your R API implementation by introducing the asynchronous programming model which will ensure your application use the web server resources in the most efficient way and to close I'll show you how your rest API can nicely integrate with the front end to light up a modern user experience in order to take this course you should have some basic knowledge of C Java or a similar object oriented language you should also know the essentials of web development and it would also help if you have some experience with relational databases however this is a beginner level course so you don't have to be an expert on any of these topics since we write every line of code from scratch and everything we do is explained in detail in terms of the software prusy for this course you will need to download and install the following the net software development kit or SDK which includes everything needed to build and Run net applications and visual studio code a lightweight but powerful seource code editor that you will use to write build and debug your code please go ahead and install these tools Now using the URLs on screen if you don't already have them you will also need a few vs code extensions but we'll get back to those later in the course with the net SD and vs code installed let's see how to properly configure your development environment let's see how to configure Visual Studio code to work with SPN net core applications now Visual Studio code is a very powerful code editor but we're going to need a few additional extensions to improve our C coding experience and also to be able to interact with our res API so the first thing that we're going to do is just head in into the extensions view right here so let's go into the extensions View and then let's go ahead and look for uh the C dev kit so you want to just type c here and the first kit is going to be likely the C de kit so this is extension that you want to install so just go ahead and click on install on this one here and the dev kit is really the an extension provided by Microsoft that is going to overall improve the experience of coding C and working with C projects in Vis Studio code now this extension does not install just one extension so let me show you that uh this actually installs a few extensions if I just clear C here this is going to install uh to start with the c extension this one over here which adds the base language support for C inside V code so that it can recognize all of the C syntax it of course it also installs the def git itself which is the extension that provides additional um improvements to V code things like for instance a solution Explorer so you can more easily manage your C projects and um create C files and also so that you can run and create test projects directly BS code uh all of that is included with a c dead kit it's also going to install as you can see down here uh in code for C de kit which what it does is just adds a little bit of AI assisted development as you're typing your C code and lastly it also installs theet install tool this extension over here uh which what it does is is really a tool that provides the net run time or the net SDK to other extensions if they need to and so that is what we need in terms of C development now the next extension that I recommend you install is one called rest client now this extension this is an open source free extension that uh that I'm going to just go ahead and install by the way so let's go ahead and install it and this is going to improve the way that we can interact with our web apis or res API directly in Vis Studio code and we're going to see that um later in the tutorial and the last extension that you should install is an extension for SQ light okay so it's going to be the very first one over here SQ light by Alex cbcc so let's go ahead and install it and this is going to allow us to very easily interact with the SQ light database that we're going to be using across the tutorial all right so yeah so those are the extensions that we're going to need and so let's now close this and let's close this pane over here now the next thing that we should do is to make sure that well that net has been properly installed in the machine right just like a save check so let's go ahead and open our terminal and to do that what you can do is just go into your menu bar terminal new terminal over here and by the way a quick chart code for this at least on Windows is either control TI right you type control TI is going to toggle that terminal for you or you can also do contrl J is a nice way to open and close this terminal very easily all right so now in terminal what you want to do is just verify that net is in the box so just type net D Das version and that's going to print out the version of the net s that you have in your box you can also do ninfo and that's going to give you even way more information about everything that uh is related to the net SDK installation that you have in your box and with that done let's see how to create our web project now Vis to code and by having the net SDK installed there are a couple of ways to create your net projects the first way is directly from the terminal so here in the terminal let me go ahead and just clean this very quickly CLS and one way that you can do this is using directly the net CLI or command line interface so all you have to do is just type net and then you can type new and this allows you to pick from a series of templates to create your projects now what what templates we have available here all you have to do is just put here list hit enter and this going to give you the full list let me expand this this giv you the full list of all the POS ful types of application that you can create with your local SDK installation all right so for instance if you want to create a web project you could choose this one template here for instance hbnet C empty web right that will go ahead and create a fairly empty a that that web project however since we installed the C dev kit um there is another way that you can also do this so let's go ahead and minimize the terminal over here let's actually close it for a moment and what you can do is just use your command plet by going into your menu over here so just go into your menu into view Command plet right there which by the way you can easily access by just doing control shift p which I'm doing right now control shift p we'll go ahead and open this Comm plet is super useful there are many many many commands available here uh across the many things that Vis Studio code can do now in this H in this command pette all you have to do is just look for net and then look for new project which is the first option over there click on that one and this is going to go ahead and open up the list of available projects to install so the list is not as comprehensive as with the c which is why I I like to always know how to do things via the CLI and not just via these different menus uh but here we have a handy way to to do this right so what we want to do is to pick a template that lets us create a project for a res API now we could go ahead and choose the aset core web API project template over here which is what you would use if you're are more experienced with web API development but if you're new what I recommend is that you start with the xet core empty template over here because that will go ahead and create only the minimal set of files and configurations that are needed to get started and then you can learn slowly how the different additional pieces are going to fit together right like Lego pieces you're going to learn how to stack each of these pieces and what what exactly is each of these pieces doing right as opposed to start with a bunch of files and configurations that you may not understand at the start okay so we're going to go ahead and create a brand new application with esinet core empty web so let's click on that one and this is going to ask us to choose a directory where we want to create our project right so I'm going to be using my D projects directory here you can use any directory in your machine but what we want to do here is to create a folder that represents the project or the application that we're going to be working with in this case what we're doing is creating an API for a game store and specifically the API to retrieve or to manage the list of games the video games in our game cap so because of that we're going to be creating a brand new project over here brand new folder sorry which is going to be named game store okay so I'm going to double click on that one so we select the game store directory I'm going to click on select folder down here select folder and that is going to make it so that vs code opens that directory turning it into the workspace where we're going to be creating all of our projects now from here the last thing that we have to choose is the actual name for the project that's going to represent in this case our API our game store API so for that one let's go ahead and type gam store. API let's hit enter and now vs code opens like I mentioned our directory our game store directory and as you can see on the left side we now have our brand new game store project created over there alongside with a solution which is the one that we can use to group the different projects that build our application right now one thing that you should notice is that there's not one but two ways to explore the files that got created for your project now the first way is of course the one that we are seeing right here right this is known as the file explorer and this is showing all of the files the physical files that compose our our current project right uh but there's also this other Explorer but you can see down here is known as a solution Explorer and this is more of um a virtual View and let me expand this a bit this a virtual view of the files that the files that compose your application where we're not going to see every single file for instance you don't see either the bin or obj directories over here they are not going to be seen here because this view is more like to help you uh manage the dependencies across different projects and also to help you create a files for C files for your solution we're going to see how this solution is going to be very handy in several situations uh but for the most part we're going to be working mostly with the file explorer which is going to be a good enough for most tasks now let's do a quick overview of all of the files that got created we're not going to go deep into all of these files but at least I want you to get an idea of what each of these files is for in your application so let's go ahead and just close our welcome screen over here and let's go ahead and open up our program that CS file here so this right now is the only C file that is available in your project and this few lines of code that you can see here are the very first lines that execute when you run your application so this is the code that pretty much boot St your application and the whole purpose of this lines here is to really create an instance of this web application of here so app here is really of type web application and web application is what we know as a host the host of your of your application now what is the purpose of this host well the purpose is really to represent or to introduce an HTTP server implementation for your app so that it can start listening for HTTP request it also stands up a bunch of mware components a login Services dependency injection services configuration Services a bunch of services we're going be going to be talking about across this tutorial and that you can configure over here if we expand this between between these two lines you could go ahead and always just type Builder Dot and this is going to give you the chance to go ahead and configure a series of services depending on your needs right uh by default as you can see there's nothing in there but we're going to be working a lot with this Builder object to introduce Services as we go across this tutorial now when you actually go ahead and invoke built over here this is going to build the instance of that web application and that's going to configure or set up a few things like for instance it's going to go ahead and set up castrell as your inprocess web server that comes in with with esinet core it also lows configurations from a few other F we're going to be talking about and also configurations for environment variables command line arguments and many other configuration service sources it is also going to allow us to send the login output into the console that we can see in the terminal all right and so after we have this instance of Apt ready then we go into what we know as as as the configuration of the request pipeline so all of these lines and let me just s here between line three and seven here is what we know as the configuration of our request pipeline so this sets up what is going to happen when requests come in how should we handle those requests right and right now as you can see really all all we have here is this one line over here which all it does it says well if a request comes for the get verb this get verb into the root of my application I'm going to reply with this Lambda expression that you can see here this is known as a Handler it just replies with a hello world that's as all it is doing right now very very simple but you can use this app object also to do a bunch of things like if you just type app here you to see that there are a bunch of things that you can do uh to modify what happens when this request come in right that that's done as a request Pipeline and again we're going to see how to take advantage of this app object across this tutorial okay so yeah that's it for the PRS file for now now let's take a quick look at the other files are available here another very important file is is known as the project file this gam store. api. CS Pro what is this file for now this this is known as a project file and this one defines a few things like for instance what type of project that you have here so as you can see at the very top here we're using the SDK microsoft. net. sdk. web that means that this is a web project that we want by default to import a bunch of libraries and dependencies that are specific for Web projects there are many other types of project that you can create with net but in this case we're focused only on Web projects and then if we go down here we going to see that we have our Target framework so in this case it says net 8. Zer that means that we have access to all of the apis that are available in version 8 of the net SD right so if you have a lower version it means that you have access to likely less apis you have a higher version you have access to newer apis right by the time that I'm recording this the version of the SDK that I'm using is version 8 so that's why it defaults to net net data Z right and then there are also configurations for other C features that are not going to dive in into right now but another thing that you're going to notice in DCS spr as we go through the tutorial is that this is where we're going to be declaring all of the dependencies or other libraries that that we may want to use to take advantage of their functionalities without having to write our own code we're going to see that as we go across the tutorial now let's go back into our Explorer here and now let's take a look at are ABS Json now we have Absa Json and Absa development Json so these are the files that are commonly used for configurations right so this is where you would put everything that should not be hardcoded into into your code base but more represents a set of configurations that could change across environments right so for instance right now we already have some configurations for logging right uh but we also have this ABS since that development Json that we could use if we wanted to so that it only works in the development environment so in your box but these settings will not be us it as you move into production for production you could either use ABS in Json or you could introduce other set of configurations from other sources and we're going to be talking about those configurations later in the tutorial right now another file that we have here is under properties there's this launch series that Json file let me collapse this for a moment now the main purpose of this launch S Json is to provide you what we know with what we know as profiles right and we have two profiles here we have an htd profile and down here we have have an https profile now these profiles provide you with some configurations only for development so this is just for local development um that kind of impact the way that your application is going to run in your box for instance this setting here states that the browser should open anytime you start debugging your application and this one here is the URL that's going to be assigned for your application when you started this URL by the way this port over here is automatically generated so you will likely get a different one when you create your application there's also something like environment variables as you can see here this environment variable H netod environment is a well-known environment variable that tells the netor time or ESP cor on time that we are working in a development environment not in a production environment right and so nothing in this file is going to available in production so when you go into production all of this goes away and you're you get actually into production context so all of this is really meant for local development now just like you have HTTP if you wanted to run with https you can take advantage of the https profile which is going to provide a another URL over here as you can see this will be the URL for https access all right now what else we have here well we have our bin and obj directories which is really where our temporary files I mean in obj is where we're going to have our intermediate files as we go into the compilation process and later in bin is where we're going to have the final DLS or assemblies for our application okay so that's it really for for the files that we have in the application let me collapse this close this and close them now how do we actually build this project how do we end up I mean going from the code into the the binaries so that's that's we we know as a build process and it's actually very easy to do so let me collapse this H there are a few ways to build your project in BS code now one way and I think the easiest way to do it is by using the solution Explorer if you go to solution Explorer down here I'm going to glap that one for a moment all you have to do is just right click in your project over here G store. API right click click on build and that's going to go ahead and keep kick off the build process based on the solution that you have currently right and as you can see right here we have our dll produc it as it says right here gam store. api.dll where is it actually leaving where if we go once again back into our file explorer into bin let me expand this a bit uh there's bin debug because we are in the debug configuration and net 8 Z because that is the framework that we're targeting we're going to see that we have our gam store. api. so that represents the actual assembly or the compiled version of our application okay and so yeah and that's that's one way to do it uh but like everything else I recommend that you also know how to do this from the command line C and so to do that what I'm going to do is just click on this plus sign over here to open a brand new terminal plus and then perhap I'm going to delete the other one I'm going to click on this delete over there and then to build your project all you have to do really is just type net so net C and then build uh that's going to go ahead and and build whatever solution or project you are in so since right right now I am at the rout at game store it builds the solution game store sln that includes the project that I'm working on right now okay so that produces the the D and one last way to do it if you wanted to do is to by by using control shift V control shift V which is going to tie into the native BS code integration into what we know as build tasks right so as you can see it already knows that our our build task is do net build so you can just click there and that's going to go ahead and kick off the build process right so many ways to do it so you can choose whatever was best for you now how do we actually go ahead and run the application right now we know how to build it but how do we run it it's actually very straightforward easiest way to do it is by just hitting the F5 key so if you just hit F5 that's going to go ahead and open up this dialogue that you can see here asking you to choose what is going to be the debugger for your application right because this is going to actually go into a debug session not just run the application but into a debx session now of course we're working with a c application right so you want to pick C here right and now you have to pick what is going to be your your configuration that you want to work with like I mentioned before uh in L Json we have two profiles one for HTTP and one for https and there is also the concept of the default configuration which is going to be really the HTTP configuration so let's just go ahead and click on the default configuration and now BS code is going to go ahead and build the project and then it's going to kick off the debugger with a with a debugger attached into the application and as you can see it even went ahead and open my browser and let me expand this for a moment it open my browser and it went into executing a get request into the API right and as you remember if you go back into vs code what happens if somebody executes a get request if we go to per that Cs and then for a moment we expected to return a hello word and because of that that's what we're seeing in the browser right now you're returning hello word notice that we are right now at the host and Port that was specified in lunch settings that Jason right so Local Host 52 74 would match what we have set in properties launch sa. Json is going to be up here Local Host 52 oops 5274 right so that's what got launched over there but then like I mentioned this is not just running application it's actually inside a debu session and how can we tell that we are actually in a Deb session though let let me show you that so let me go back into vs code and I'm going to temporarily just stop the debugging session for a moment so you can see we have this stop Buton over there we can use to just stop the debugging session so I click on that I'll click close this and I'm going to place a break point in my Pam CS over here perhaps over there which is where we are configuring our get request and later executing our hello word land over there so now if I hit F5 once again H BS code is going to build the project and attaches a debugger into the application and as you can see this time we actually a stop over here in the breakpoint line five H and from here we can go ahead if you wanted to and start evaluating the different objects that are live now in the application right so we could go ahead and hover over app for instance and that's going to give you give us the values of the different objects that are available right now from from AIT core right the web application object and not just that we could see variables I mean the Builder the app on the left side we could add what we could check out the call stack also if you wanted to but indeed we are in a debugging session and to continue all you have to do is just click over there over here click on that play Buton and that's going to continue the execution now this opens up the browser once again browsing into the root of the API but we have hit the breakpoint once again and that is because now we are inside the Lambda that executes when the actual request lands right the first time it executed because we were booting or St star up the application and now we actually hit the get endpoint and we are invoking the this hello word L okay so just click on play once again and back in the browser you're going to see that it presents the hello word once again okay so that's how you can I mean easily start debugging your application now what if you don't want to go ahead and debug all the time which is would that would be my case like you don't need to be debugging all the time because it can be a bit timec consuming if you keep doing that over and over again so what can do and let me just back here stop my debugging session what you can do is either go back into Explorer right you can go into solution Explorer and you can right click in your project over here you can go ahead and say debug and then you could do a start without debugging right start without debugging so this is going to start your application without any debugging support notice that it was way faster still opens the browser but it was way faster right or another thing that you can do right let me stop this once again stop that which is is going to be also my favorite here is going to be by using the terminal directly so if we collapse this for a moment and let me expand my terminal going to Cod these three dots and into terminal over here I'll kill this terminal back into this simpler one okay and I'm going to switch into gam store. API which is the location of the actual API that that we have created and I'll just type net run by doing that once again I'm running the application right but there's no debugger attached and we are going to see in nice colors the the logs that are going to pop up out of the application and we can clearly see where is that we're hosting the application Local Host 5274 so by being here I can again once again go back to the browser just refresh this and again it's going to send back hello word right and so now that we understand how to create a project and how to build and run it uh let's now switch into slide to understand much better what exactly is a res API in this section you will learn what are a res API is and how it relates to Modern client applications to understand what a res API is start by thinking about all these apps you have in your phone like your weather app LinkedIn or Spotify these apps use a ton of data like the latest weather information the latest post in your LinkedIn feed or the hundreds of songs in your favorite playlists however that data can't leave in your phone which is what we know as a client because it will be way too much data to store in your device and you want fresh data all the time anyways so the data has to come from someware and that someware is going to be some sort of server computer that usually leaves someware in the internet Cloud but how can these apps talk to that server in the cloud to retrieve that data well by using an API API stands for application programming interface and it's how a service defines the functions it provides to clients so for instance going back to the Spotify example the Spotify cloud service could Define an API with two functions a get recent songs function that receives the username as a parameter and that Returns the 10 most recent songs for specified user and there could also be a play song function that receives the song name as a parameter and that Returns the stream for that song so that a client can play it like this there could be dozens or hundreds of other functions offered by the service that clients can use to interact with it so an API helps clients communicate what they want to the service so it can understand and fulfill the request rest stands for representational State transfer and it defines a set of guiding principles that impose conditions on how an API should should work we won't dive into each of these principles in this tutorial but the important thing to know is that thanks to them you can build apis that are scalable flexible and independent of the technology being used on the client and the server so going back to the original question a rest or restful API is one that conforms to the rest architectural style now the main reason why we want to stand up a rest API is so that our clients can interact with the data that it manages but how do they actually reach that data well for this it's good to First understand the concept of a resource in a res API in a res API a resource is any object document or think that the API can receive from or send to clients for instance in our game store application the main resource is going to be our games that's what clients want to query and modify but in other applications like the Spotify example one of the resources could be the songs and in in the LinkedIn example one resource could be the users and another one the LinkedIn posts these resources will be hosted on some domain which could be a public domain an internet location or it could be just your de boox and they can be accessed either via the HTTP protocol or the https protocol which is a must in public environment so when you combine all these you get what we know as a uniform resource identifier or URI and that is what your clients will use to identify and reach resources of a res API there could be more parts to this URI but these are the essential elements now how do you actually interact with the res API well just like with traditional web pages when clients want to request something from the servers they will send an HTTP request using the resource URI to the server and then the server will send back a response however in rest apis these requests and responses will look a bit different depending on the specific HTTP method used to call it the most common methods are post which creates new resources get which retrieves the representation or state of the res resource put which updates an existing resource and delete which deletes a resource so these methods allow you to create read update and delete resources and therefore they are also commonly known as Crow operations there are other methods too but for the purposes of this tutorial we'll focus on these four ones let's take a look at each of these methods in the context of our game store example to understand better how they work to request all games a client will send a get request to the game's endpoint and the server will respond with something like this the first part of this response is the status which is 200 okay in this case this means that the operation was a success there are many other HTTP status codes that AR rest API will send back depending on the result of the operation many of them for failure scenarios the next part is the body which contains the list of games in this case notice that this body is not HTML but instead the format of the response is known as Json which stands for JavaScript object notation this is the de facto format for sending and receiving data in res apis because of how easy it is to read and write and is supported by all major programming languages If instead of getting all games you wanted to to get a specific game you would again send a a get request but this time you would append the resource identifier at the end number one in this case the server will respond with the state of the game with that identifier assuming it's able to find the game to create a game the client can send post requests once again using the games resource URI but this time it needs to specify the desired resource state in the body of the request which in this example only includes the name of the game but could include many other properties of course the server will usually reply with a 2011 created status code and if the resource identified was not specified as part of the request body the response will usually included to obtain an existing game the client sends a putot request with the same resource URI as they one to get a game but this time it includes the resource State just like in the post scenario the server will completely replace the state of the game associated with the specified identifier with a new state and will typically respond only with a two or four no content status code finally to delete an existing game the client sends a delete request to the URI that identifies the game to delete and after deleting the resource the server will usually respond with a 204 no content St status code so in summary your complete games res API would look like this and should offer all the support that your clients expect from a modern backend let's now jump back into the code to see how to implement this res API in a net core before we start implementing our net res API we need to find a better way to interact with it and that is because the browser is not really designed for this kind of work and you can only do so much from the browser so instead of using the browser what we're going to do is find another way by using directly Visual Studio code to talk to the API and let me show you how that works so back in BS code in our file explorer let's go ahead and just right click on our project folder gamest store. API in this case let's do new file and let's name this file games. HTTP the name of the file doesn't really matter what matters is extension and this file is recognized by the extension that we sted before this one called rest CL that extension allows us to write a statements directly in this file that very quickly allow us to interact with the API so for instance remember that we have our hello world declar over here right so far this is all we have how do we interact with that well all you have to do here really is just say get because it's going to be a get request and then we want to specify the host and Port of our running API so to figure that out remember you can you can always always go into launch sajason look at your HTTP profile this profile over here HTTP and here is your application URL so I'm going to copy this close that I'll just paste it over there and now we are pretty much ready to talk to the API so how that work so let me collapse this let me open my terminal I'll do contrl J to open my terminal here I'll switch into gam store. API and I'll just do net run right remember that there are many ways to run your application this is just the way that I I like to do so so now what I can do and I'm going to collapse this for a bit what I can do now is just right click over here where I have declared this line line one I just right click and I'll use this this option here that says send request send request click on that one and on the right side I'm going to C the terminal you can see that we get a response right away including the hello world that we were already expecting that we were seeing before in the browser now we're seeing it here and not only that we can also see the status code of the response and a few other details about this this response and so you can also go here I mean there is this send request link over there that you can always go ahead and click it's going to have the same effect I have found that at the time that I'm recording this this link is not super reliable so sometimes it may not work so that's why I prefer to do it the other way but another way to do it is also do to do Control Alt R in Windows at least Control Alt R is going to go ahead and execute the request for you so as you can see this is a much better way to interact with the API but one problem that we still have is that anytime we start a debugging session the browser is is still going to open right so if I just close this and let me open up my my terminal over here I'm going to do contrl c to stop the process process stopped now I'm going to do F5 to start a debugging session and what's going to happen is that of course it it builds and the breakpoint is been hit I'm going to remove this breakpoint and then the browser opens again right so this is not something that I like because we're not going to be doing anything with the browser and even a debugging session I'd like to just stay within BS code so how to prevent the browser from opening so let's go back to BS code and let's stop this debuging session what we can do is just go and I'll do control shift e to open my Explorer View and I'll go into my launch settings at Json file right and so in this file all you have to do is just switch launch browser from through to false and I'll do that both for my HTTP and my https profiles right we're not going to be using really https but just in case uh let's switch it in both sides all right and just by doing that if I hit F5 once again I'll hit a five you're going to notice that we just remain within BS code and if I want to I can go and just close this and I can go ahead and right click in my gam HTTP and send a request right which now it is sending the request but we are in the context of a debugging session which is going to be super handy in many occasions all right so yeah so let's now stop this let's close this this and this and let's go back to the Explorer view control shift so now it is time to start the implementation of our API uh but there's one thing that we're missing so far and that is a way to represent the resources that we're going to be managing in this API right like we said we're going to be managing games video games right it's a Catal of video games that we don't have a way to represent those if you remember if you go back into pram CS I'm going to collapse these properties also in pram CS uh we have already defined this one well by default we get this map get that all is doing is just returning this hello word right which is a simple string but in our case we may want to have multiple properties that are associated to our games that we're going to manage so things like an ID a name and a few other things right so what we're really missing here is what is known commonly known as a data transfer object now data transfer object or dto is an object that carries data between processes or applications it encapsulates data in a simple and standardized format that can be easily transmitted across different layers of an application or across different applications so let's see how can we go ahead and Define a dto to represent our Gams so let's go ahead and just close this file and for this we're going to be using actually the solution Explorer down here solution Explorer let's open up that uh and we're going to be using this anytime we want to create either folders or files for our project because it's just easier to do it here than in the standard Explorer so right click on the G store. API let's add a brand new folder we're going to name this folder dtos now keep in mind that other folks like to name this folder contracts as opposed to dto which is totally fine because a dto can be considered like a contract between the client and the server because it represents the shared agreement between client and server about how the data will be transferred and used so if you want go ahead and name these contracts that that would be totally find is just really the same thing now in this directory let's right click on the TOs let's create a br new file it's going to be in this case is going to be a record not a class but a record right and let's name it game dto okay now why why are we using record types here as opposed to a standard class well the thing is that by default records are immutable meaning that once their properties are set usually at the time we create these records they cannot be a changed right and this immutability is a perfect fit for dto uh because they typically carry data from one point to another without the need for modification and on top of that records reduce the boilerplate code that is typically associated with class definitions intended for data holding like DTS as as you're going to see you can Define these records with just a single line including all the properties which simplifies the code base and makes it much more readable and it has I mean record types have many other benefits but these are the main ones that I see that are very useful for dtos right so let's go ahead and let me collapse this so how do we Define this EO first thing that we should do here is to actually match the Nam space with the file structure so let me open up my explor again remember that this is under our DTS directory and because of that I like to always follow the structure of my file system I like to follow it also in the name space so for that you can either type here just. dto or you can use this this liel over here you can click on that and you can select the option that says change namespace to gam store. api. dtos right so that's going to make make it so that it matches right let's collaps this and now let's define the properties for the dto now D is actually very easy to Define we don't actually need this coolly rases all we want to do is just open parenthesis here and here we can start declaring our properties the first one is going to be our ID that's going to be an INT int ID and then the next property is going to be a name uh let's follow that with a gener so gener is like is it sports racing role playing whatever kind of game we're dealing with we also have a price and then at this point by the way let me just send this to the next line so we can see better what we're working with here okay we have the price and lastly we're going to be specifying a release date for that one we're going to do uh date only date only release release date and we're doing only because we don't really care about the time all we care is about the date portion of the of the date when the game was released right awesome so now we have our dto ready and now we're ready to go ahead and start taking advantage of it so for that let's go ahead and open our Explorer view once again control shift e and let's go into program CS let's collapse this now as we start writing the next few lines just keep in mind that our API is going to be evolving across this tutorial right so you you may see that the initial code that we write for this is going to be a little bit dirty and odd uh but is is meant to start like that just so that we can solidify the initial concepts of res apis first and then we're going to see how to refactor and get into a a much better implementation and in that sense what we're going to do here is to define a very simple list of games in memory using our dto class we're going to see how to implement the different HTTP methods along or around that in memory lease later in the tutorial we'll see how to transition from that me in memory lease into an actual database so what we're going to do here is just perhaps just after the the definition of our web application object over there we're going to declare here a simple list of our game dto right and notice that by selecting game dto BS code automatically added a using a statement over here game store. api. dtos right so that it just did it by by itself and that what that's what gives us access to the game type now the name of this is is going to be just games and we're going to Define that list right here now I have already prepared a small list of games just for us so just so that you don't see me typing so much so let me just go ahead and grab that list from my other window over here as you can see I have now three games right so here is just my favorite games right so ID one is going to be Street Fighter 2 the generator is fighting now we have the price here and we have an M here because we want to specify clearly that this has to be a decimal right otherwise we're going to be we're going to get kind of a warning here because the compiler will not know if it's decimal or double what is this right so it's going to be decimal in this case and then we have a date only in this case here's the date for that first game and then scrolling down we have a id2 Final Fantasy 14 role playing here's the price here's the date and lastly we have another of my favorite games FIFA 23 with ID3 Sports here's the price and finally the release date all right now how how do we go ahead and actually uh Implement an API that can return these games over here right and so for that is actually we can actually follow the pattern that we have down here right so what you do is you say okay you use the web application object and you say okay so what kind of a verb I'm going to implement in this case we want to do a get right a get operation so it's going to be map get and then you want to specify what is going to be the path under which this endpoint is going to be located right in this following proper rest practices we should name this as games because the API is going to be all about managing games now notice that this is not going to be named just game right it is game in plural because that is the way to address the group of resources you're going to be dealing all right it's very important to keep those conventions like that now after you define that pad what you must specify is is the Handler right so how are you going to be handling a request that comes into that pad so in this case really all we have to do is just return that Lista we have in memory there so we're going to do just this games so this land Expressions just says that we're going to be returning whatever is in the games list over there and really all that's all you have to do and this is really why this type of API is known as a minimal API because it is very quick very easy to to declare as you can see over here now let's see how what how that works uh in practice so I'm going to go ahead it and just run my API once again and I'm going to click on these three dots into go into terminal and I'm going to delete this last one so I'll just do net run all right net run and then what we want to do is just go back into games. HTTP and what we can do is just modify this one uh request that we have here to to actually Target our API remember that it is under the games games pth so I'm going to just copy games over here slash games and that's pretty much it so I'll just right click I'll do send request and as you can see on the right side we get a 200 okay response so it was a success and down here we have the actual games so notice that we have here Street Fighter 2 we have Final Fantasy 14 FIFA 23 it's all there and then like I mentioned before this is a Express in Json right so espinet core took care of Transforming Our C objects serializing them into Json a as you can see right there all right so yeah so that's our get endpoint and then now let's go ahead and close this and let's go back to pram Cs and let me also control J to open my terminal contrl C to stop it uh one thing that we may want to do at this point is just get rid of this hello world because we don't really need it anymore so I'm going to rep it now just so that we can keep track of what exactly each of these endpoints is expected to do I'm going to add a little bit of a comment here so this would go for a get get games right so whenever somebody goes into get games uh this is the that's is going to respond okay just as a little bit of documentation now what we want to do now is to perhaps create the request that can be used to retrieve not all the games but just one game how would you do that get Again by ID so it's a very similar idea actually so what I'm going to do is just say perhaps let's do the documentation first it's going to be something like games slash a one for instance how do you represent that so app mapet okay and so again we start with games but this time we need to provide one more thing which is going to be the identifier in this case so for that in this what is known as the pattern we can specify with this corly Braes we can introduce a kind of um the variable that we're going to be using to receive that ID right so that goes in the row template and then in the next parameter for the Handler what we're going to do is now not receive just an empty argument list but we can actually receive that ID that we specified there with the exact same same name int ID right and then this leads us into the actual execution that we want to to perform here so what we want to do in this case well just find the game that has that ID so for that we can just use uh the find method of of Leist so games to find and then we will do game where game. ID equals the and just like that we should be ready to go ahead and query for for one specific game so once again let's run our API the that run in the terminal close this go back to G HTTP and what we want to do now is to H just add another request here now to separate your request in this file what you want to do is just introduce these three pound signs and then you can add your request and I'm going to copy the first one down here notice that because we have this three pound signs we also get the send request link over there which means that it is recognizing it so we without without these ones it would not do that right it just goes away make sure that you add that and now that I'm here I'm going to um just append slash and then we want one of the games so let's do number one and then let's right click let's do send request and on the right side you're going to see that we are indeed getting that game number one right you can see it's game number one right so yeah very simple and very very similar to what we did before right so let's close this and let me control C stop my server back to Broncs before we move forward uh notice how we keep using the proper rest notation as we Define our end points right so for instance in this case when we did games by ID we prefixed everything with the name of the resource or the plural of the name of resource in this case games and it has to be like that right so you cannot say something like get games right that will not be correct it has to be games or you cannot even say something like um games uh games by ID and then something like this right that will make no sense so to follow proper reson notation you always start with the grouping or the the term that represents the group of resources and then you follow when you want to specify something or find something by ID you followed by with the IDE of the identifier or of that resource right so this is the right way to define resources in rest if you're not doing it this way you're not doing res right so now let's move forward to the creation of brand new resources how do we do that well we have to create a post end point for this but before we can do that we need to Define how is that or what is going to be the representation of those resources we're going to be receiving into that ID it is it is similar to the one that we're using today for I mean the game dto for return resources but it's not exactly the same one right let me show you how this should actually look like so let's let's go back into our Explorer over here and we are in solution Explorer and what we're going to do is right click on DTS and create a brand new file and again it's going to be a record not a Class A record and this one is nam going to be named create game dto all right and then once again let's go ahead and fix the name space and here's one tip for you uh anytime you see a libel over there instead of clicking on it you can just do control dot control dot is that that's going to open up this context menu and then you can pick whatever makes it this case change name space to Gam store. api. and that will fix that now to Define thisto here we could grab a bunch of the properties that we have uh in our other I mean in our game DT over there let me let me go ahead over here I'm going to paste those but there is just one difference I'm going to paste those over here and the difference is that when we create again we actually don't have any ID right the ID is going to be provided by the by the server by the API itself so we are not going to require clients to send us an ID because of that we're going to be removing this from there so we STI with the name the gend the price and the release date now this the is going to be changing later on in this tutorial this is just an initial version but for now notice how the contracts that we're going to be using either for returning data or for posting data into the API uh may be different right so that's why we want to be very specific on what we're going to be requiring from the client for each case all right so now that we have our create game dto let's go back into to pram Cs and we can go ahead and Define our brand new endpoint so the endpoint is going to be for the Post Verve when somebody post something into the game's handpoint and just as before what we can do is just say app that in this case is going to be map post okay and of course it is when somebody post something into games and in this case in our Lambda what we're expecting to do is to actually receive a object object of the type of our dto the run new create game dto and let's just name it this one as new game all right now what are we going to do in this case so let's go ahead and actually expand let's have a body for this one so we can be a bit more verose in this case what we want to do is just to uh kind of convert this create game dto into a normal game dto just to add it into our inmemory Leist for so for that let's just do game dto G it's going to be a new okay and let me open and close here so the first parameter here of course is going to be the ID so what is going to be the ID of this game now how are we going to come up with an ID Well for now what we're going to do is just add a plus one to whatever count of games we have so far so in this case we're going to say games. count and we're going to say just plus one all right that's going to be our ID then we go for for the name so that's going to be new game. name and then we go for the generate so new game. gener then new game price and lastly new game release date right so that's going to go ahead and complete the definition of our brand new game and then let me scroll down bit we can do is just say games. add our game right so the game is part of our list and lastly what we want to do is return something back into the client to tell the client what was the result of the operation did it succeed did it fail what happened and we can provide even more details and the standard in this case is to return a 2011 created response how do we do that so all you have to do is just say return and you can use the results class right so this a this a buil-in class in infinite core results and then this contains multiple prebuild responses that you can use so you don't have to manually specify the status of the response so in this case we're going to say is created at Route okay and then we use this because with this we can provide a location header back into the client so the client knows exactly where to find the resource that just got created so how do we do that so the first parameter here is going to be the the name of the route where the client can find that resource now we have not actually defined the name of that route so far uh but but to do that that what we're going to do is just go back a little bit into our map get by ID route over there and just before closing this we're going to just do here dot with name right and this is a method that you can use specify to give give a name to this Endo that we have defined because it doesn't have a name so far so what name we're going to give it so let's just name it get get game okay so get game and then now and now we can use this exact same name down here in our order in our return created by ad route get name get G and C is going to take care of figuring out what is the route to to that endpoint right and to use it to build the location header to return back to the client okay the next parameter I want to specify here what is going to be the the value that needs to be provided to the get game route remember that get game receives an ID right here it receives an ID and so we need to provide that ID back into the response that we're going to provide here for that we're going to be using I mean the standard is just to use anonymous type so we're going to say new and in this new we're going to declare that it has an ID and that ID is going to be game. ID the one that we autogenerate last parameter here is going to be the actual payload that we're returning back into the client if you want to return a payload so for that we're going to be using game all right and so now just to keep things a little bit cleaner uh what I like to do is is is to not have this name repeated twice right over there and down here and instead of that let's define a constant that we can use uh to refer to this to this value so let me just copy this and let's go all the way up here okay before declaration for list we're going to define a con string this let's name this one get game and point name and that is going to be get game okay so now we can just copy this constant down here we can replace that in with name right here this is the get game m point name and down here we can use it all right that way we avoid having this hardcode this all right so with that in place we are ready to go ahead and test our brand new post endpoint so open the terminal and I'm going to just do net run all right so it is running so let's class terminal let's go back to gam HTTP and of course what we have to do is Define a new request here so triple pound over there and then we're going to be doing a post request it's going to be same endpoint right with no ID right it's just the endpoint games endpoint and then one thing you have to specify here is the content type right so so that we can tell our API what kind of content we are sending over there so in this case it's going to be content type and the content type in this case is going to be application Json right and then uh in this case we'll have to Define just leave one empty line over there you need to leave this one empty line and then in the next line this line 10 in this case we're to define the payload of our of our game we're going to be Crea remember that the payload has to include a name general price and release date as per our create game dto so back in HTTP here's HTTP uh I'm going to Define that but just to not write too much I'm going to actually copy it from my other screen over here here's our first game so this is going to be as you can see it has a name gener a price and a released right in Json format so we that in place and since our server is running we should be able to go ahead and ex execute this so I'm going to just right click here and I'll say send request and as you can see on the right side we are getting the expected 20 one created response over there okay and then down here we can see the payload that represents the game that was created right notice that it has the id4 it's a fourth game in our list and it not just has the payload down here but it also provides us with the location header right notti this here here's the location header uh that ainet core created for us because we provide Ed the the right values for the created at Route method that we us right and so and since we have this the client knows that now the client can just use this I'm going to copy this I'll just copy that close this and the client can go and say for instance let's say over here we can replace that and now we can right click and send send request and now the client was able to query for that brand new game right there game number four and of course if we execute the first request we should be able to see that we have total of four games over here one two three and four here's the four games all right and yeah that's it for the implementation of our get a let me just stop my server here and let's go back to prcs so now we're able to query for games and create brand new games so how about updating existing games right so for that of course we're going to be needing a a put endpoint but before that just a before we need a brand new dto to represent the payload that the client should send when they want to update the resource so let's go back into our cont shift e our Explorer here this is solution Explorer right click on dtos add new file record and then this is going to be named update game dto now we could certainly just use create game dto for the same purpose uh but really the convention is to always specify a brand new contract or dto for every single new operation because eventually things could change right it would it could be that you may need to do something different for upd dates that is not needed for a creates and so I don't want to be messing with those contracts so just keeping them separate one for each operation right so let's go ahead and collapse this and I'm actually going to H go ahead and grab what we have in create right now so I'm going to copy this into update because like I said right now it's the same thing could change later but for now it's just it's just that and with that dto in place let's go back into program. CS run that CS over here and let's define our put endpoint so I'm going to move down here let's go and do this so we can see better and let's define our app and by the way let's define that this is going to be for a put into games right and so app. map put in this case map put and then once again this is going to go into games and then just like in get by ID we need to specify what is going to be the ID of the resource that needs to get replaced right put in here means replace resource with whatever I'm going to be send okay and then uh we are going to specify two parameters in this case h is going to be inside our arguments Lambda um the ID we need that ID that we just specified in the template and then of course the update game dto updated updated all right now let me just check one thing yeah we forgot to fix name space over here we should always have the the correct name space so let me do control dot here to change space to G store. api. dtos all right and then what do we do about the body of this Bo so let's open up our body for the Lambda right there and what we're going to do here is just H find the game in the list the existing game in the list for the ID provided and we're going to then replace that game in that list with a brand new representation right so so let's first find find the index of the game so we're going to say index it's going to be games. find index and then for the game where game. ID is it that we got as a parameter so that gives us a in game and what we can do now is just go into our list games and then at the index of the found game we're going to create a brand new game dto right so let's open and close parenthesis and then of course here we're going to be just filling the filling the slots right so it's going to be the ID and then we have updated game. name updated game. gener updated game. price and updated game that release date all right and so with that we have replaced uh the the game in the list and last thing is to return something back to the client now the convention for an update is to just return no content right so return results. no content and that will be pretty much it for our put operation now uh you may notice that there we are not covering all of the cases right in this API so far like what happens if I cannot find the game right so we're going to go back into those uh later in the tutorial for now I just want to get a complete set of endpoints that we can work with and then we're going to go back and start refining these endpoints with whatever pieces we are missing okay so for now just happy back so now we have our input defined let's go back into our gamat HTTP and let's see how we can query a send a request for this put endpoint so just like before we're going to open a brand new section this is going to be a put right it's a put request now let me just copy this the endpoint goes into SL games but of course like I mentioned we want to specify in this case we need to specify the ID of uh of the of the resource that we need to replace so in this case it's going to be SL one let's say for to replace the very first game that we have in the list and then well what is that game so to know that let me actually start our server so let's go ahead and do net run so we can start a server let's query for all the games right so in this one here right click Send request right so what is the first game is this one here Street Fighter 2 what I'm going to do is just copy the body of this first game just going to copy it and then down here I'm going to use that for our put body now let's not forget to use content type application Json over here and then let's paste that down here looks like I didn't copy it properly I'm going to just grab it from my other screen there here we have and what I did here really is just modify the title right notice that the initial title uh as we can see right here was um strict Fighter 2 right price is $19.99 so I'm going to make a small change so that the game is now going to be named St fighter to turo and then the price is going to be just way cheaper it's going to be just $9.99 right those are the two changes that we're going to introduce into this game but just keep in mind that putot is going to replace the object right that's the purpose of put replace the object completely so with that in place let's go ahead and right click and hit send request and as you can see as expected we get the 204 no content that's the expectation that's good and then if you want to verify that things the the game actually changed all we have to do is just go and query for game with ID one in the get so right click Send request and on the right side we should be able to see that yeah indeed now it is a street fighter too and then we have a brand new price order right so the put operation is working as SP right so let's close this and stop our server back to pron CS now before we move on into the last operation the delete operation one thing that you have to consider here is that um er concurrency right what happens with concurrency now now keep in mind that all the the thing that we're doing here is really a starting point towards something we're going to be doing next but if you ever decide to just go into production with this in memory list of games keep in mind that this is not going to work very well because games is a simple list right so games is a simple list that we have over here and this list is not threat Save Right meaning that if you start getting multiple requests let's say into put over here right you could go run into issues right imagine multiple requests coming here and trying to modify the same game at the same time that is not going to be threat safe that's going to cause problems so don't do that in that case you want to be using something different than a Leist perhaps a concurrent back or something like that just not a simple L uh now in our case we're going for this because like I said this is just an initial implementation for you to get started with rest apis and later you're going to see the we're going to get rid of that list and move into something much more interesting right and so let's go ahead and Implement our last endpoint and this is going to be our deleted right so let's scroll down here and documentation this is going to be a delete for the games pad and then we need to specify some sort of file right so just like before map in this case is map delete map delete and we want to specify where is going to be the pad in this case just gains and then it has has to have the ID of course and then we specify what is going to be our argument in this case it's going to be just the ID in ID and then let's open up our Lambda body over there and let's see what would we do for a delete but the delete is actually as you expect the simplest thing to do all you have to do is just remove any any game that matches that for that what you can do is just say games that remove all and then where the game is game that I ID equals ID that's all and then uh the expectation for the delete is again a no content just like in the update case so you can do return results. no content that's all it is all right so and well to test this very easy let's go ahead and run our server once again the Run let's go to our file over here I'm going to grab the location from the previous request and I'm going to just add here another request down here now in this case it's going to be um delete into whatever part we have over there and then um yeah that that's pretty much it let's say let's say actually work going to the game number two right and so now before we delete let's confirm what we have initially right so right click at the very first request we have three games right now one two and three we're going to be deleting number two Final Fantasy 14 so let's right click on let's close this and right click on our delete request send request it says no content 204 no content meaning this is successful so now we can go back and get our full list once again send request and on the right side you can see that we no longer have a game number two so we have one we have three we have two it is gone so our delis is working as aect all right let's close this and let's stop our server and back into prones now at this point our API is mostly functional however we have only dealt with happy pads right so we still need to deal with a few unexpected scenarios for instance what happens if we are not able to find a game right and let's try it out so let's go ahead and run our server all right and now let's go back into games. HTP and uh let's try to find again that does not exist so if we go back into our very first request we know that we have games one two and three that's fine now let's use our second request to request game number four right what happens if we request game number four so right click Send request and what we can see on the right side is that not only we're getting a 200 okay which is already bad right because I mean there's no game why are we getting a successful result we even getting a null response down here so this is this is just completely wrong this is not what we should be returning there's a standard way to reply for a situation where the resource cannot be found and that's what we're going to cover now let's close this and let's stop our server and perhaps we can close a few of these tabs here to simplify our screen move this here so let's head back into our get by ID get by ID method over here so this one over here so first thing we're going to do is just to give a proper body to this uh to this method so let's open C right there let's do this all right like that and then what we're going to do is to actually capture the result of the call to find right so we're going to say well far gain equals games. find okay now what are we actually receiving from games. find if if we not notice closely we're receiving not just a game dto but a nullable game dto right and to make that more obvious let me just do control dot here on V bar and let's use an explicit type as instead of bar right so this is a a nullable game Theo that means that we could either receive a a game or we could receive null if we're not able to find game because of that what we can do is to alter the response to our endpoint here to return the correct response depending on if we found the game or not so we can say is well return we're going to say if game is null right so if it is null uh we're going to return we're going to be using the results results class to return not found right this a standard response where we're not able to find the resource and otherwise if we're able to find the result the the resource uh we're going to say in this case well we cannot just say game right because now we're returning two things right one side we're returning an object of type I result and on the other side we're returning an object of type gain nullable and that's not allowed that's why we have this cruly Braes over here so because of that we're going to wrap the game into results. okay okay that will make sure that for both cases we are always returning the same type of ey result all right and yeah that that's pretty much it so if we run this once again so let's run the API right so running it g. HTTP now let's try to retrieve game number four once again request and you're going to see now we get the proper 404 not found there is no null down here and this is the expected response when we're not able to find a resource all right so yeah so that fixes the case of our um if our get by ID request now let's see what to do about our put request right because I mean post is fine but put could face the a similar situation so if you're not able to find the game this find index call is going to return a min one so in that case we should not move forward and we should R again return and not found so we're going to do is just say if index is actually minus one so that's the response minus one we're going to say okay result return results. not found now one thing to keep in mind here is that returning a not found for a put call is kind of um is one of the possible things that you could do uh for put and it's not really clear in rest terms uh if this is the absolute true of what you should return because another thing that you could do in this case is just to go ahead and create the resource if you don't find if you can't find it you could go ahead and just create a brand new resource with the payload that we receive over here right and that's what many services do but many other services will just return and not found what to do exactly it is not clear it is not clearly defined so it's really up to you to decide what what to do in these cases now I do prefer this way of returning not found because in the case where you H actually choose the other option where you create the resource you run into a bit of a problem when um you move into a scenario when you actually have a database uh that is able to create the the IDS for the resources by itself um and in that case if the ID over here said well ID is going to be I don't know five and then you come here and you cannot find the resource and you go ahead and just go ahead and create a resource uh the the database will go ahead and create the resour we whatever ID makes sense right so it's out incrementing usually right and that may not match the ID that you specified here right so you get into a weird situation of what do we do about that that identifier when we are not able to find a resour with that for a put request so because of that I do prefer this method here but just keep in mind that it is totally fine to all to choose to just go ahead and create the resource if you're not able to find it in a put scenario right so let's go ahead and test this and make sure this works so net run let's go into gam HTP and in this case we're going to go ahead and try to do a put for let's say game number five which does not exist let's see what happens if we try to do that right click Send request and as you can see we are getting now a 404 Note file so our new logic is working awesome so let's close this and let's stop our termin and back to pram CS now what about our delete endpoint this one over here should we do something about the fact that the game may not be there well as you can see it doesn't really matter right because we're just removing whatever we can find that has the specified ID right and that's okay for a delete verb the object of delete is to delete the resource if if it is there if it is not able we're not able to find it it is fine the client is not really doesn't really care on the fact that it found it or not as long as a resource does not exist anymore after invoking the delete operation all right now uh well now we have our endpoints pretty much uh implemented right at least the basic behaviors and then one thing that maybe bothering you at this point is that well we have I think just too much code in our pram that CS file right so this is just becoming a big file and that's a big big no no right we should we should be able to put all this code in somewhere else to keep our PR CS as clean as possible so because of that what we're going to do is the following let's go back into our Explorer control shift e and then uh let let's collapse this and what we're going to do is just create a brand new directory in solution Explorer so gam store. API right click new folder let's name this folder endpoints all right and in the new endpoints directory we're going to right click and we're going to add a new file unless this is going to be a class and this class is going to be named games and points yeah games and points that's a name all right and as usual let's do control dot at the very top here to fix our name space so it is st. api. endpoints right there and let's class this now this is going to be what is known as an extension method as extensions class or I mean going to be a static class that's going to have extension methods which are going to be H static and the idea of this class is that we were going to be able to extend one of our classes or the classes that we don't own like the web application class so that with just one call we can map all of the endpoints that we need for our API let me show you how how that actually works so first this class has to to be static okay so we can have our static sanction methods inside and then we're going to start transferring all of the code that should not really be in pram CS anymore so we're we're going to start with this const and the list that we have here let me copy this we're going to copy that over here all right and then let's make sure that we import spaces I'm going to do control dot on game dto to use G store. api. dtos all right so here we have our Le now since we are in a class now we have to we should provide a proper ident um modifier for the type of access that we should have for this games list so in this case this is going to be a private list all right and we have cool races here because it is suggesting that we should make this field read only which makes sense uh because uh even when we may be adding and removing methods into this H adding or removing games into this list we're never going to be reconstructing the entire list from scratch right that's never going to happen and so because of that we can make it readon right now it is a readon list okay now is have squiggles here uh because we are declaring an instance member in what is really a static class right this static class so because of that we will have to make this list also static and really everything here is going to be just static now with that in place we can move forward to actually declare our extension me like I said this is a method that is going to extend the functionality of an existing class and it happens to be a class that we don't actually own but we can still extend it so let's do that public static and then we have to uh decide here what is that we're going to be returning from this method here and what we're going to be returning is just going to be the exact same time that we're going to be extend right as kind of a convention so that type is going to be web application all right that will allow whoever calls this method to just chain another call into uh into another extension method that is also extended with web application if they want to now the the name of this method is going to be map games end points and then this is going to receive web application and let's name it yourself now to make it so that this is actual an extension method all you have to do is just put this here and that turns this into an extension method so now our method is going to show up as a new method of the web application class right now what what should we put in the body here well let's go to program Cs and just grab all of the methods that Define all of our end points for our API so all of these let's copy that and let's paste those over here right so our method looks like this map gain end points and we start adding all the map gets map post map put and map finally since we are returning a web application object we should just return up okay and uh yeah that will do it for our map gain Senter end points uh extension method right we just return app at the end with that in place we can now go back into pram Cs and we can clean things up so we can go ahead and pretty much remove everything between app and app. run or we can just get rid of all of these and all we have to do now is say app. map games endpoints right so as you can see now our perm CS is very clean and I'm going to do control dot at the very top to remove on usings like that so that's all we have now in our prcs and now we have our everything that relat is related to endpoints in games end points. CS right now it it is possible to forther refactor this of course you should do that but in this story we're not going to go that deep into refactoring we want to move forward to another set of very important topics regarding R cpis and one of the topics here is the fact that if you notice we have um we have this games uh endpoint right in multiple places across the API right so we have it there we have for the map get by id M byid and then we have it for every single endpoint we have games gam games all over the place so can we do something to improve that we certainly can and to do that what we can do is just take advantage of something that is known as a group Builder right so we can create a group that defines common things across all the endpoints so that we don't have to Define them over and over how to do that so let's scroll down a little bit and all we have to do here is say well our group equals app. map group okay and in this map group we can say that okay so all of my routes for this specific set of endpoints are going to start with games right everything starts with games and with that we can take this group variable and make it so that all of the gets post and all of these calls go from group so I'm going to replace app here with group group and then the same thing for every single method here so group and then group and group okay and since we have changed everything into that group variable we probably want to also go ahead and return that group down here as opposed to the app now group does not map the web application so we'll have to change the return type into route group Builder right so let's go all the way up and let's change from web application into route group now of course what's the point of doing this well the point is that now we don't have to say games all over the place so in this case we can just say slash right because this is this get is going to go go just after the games that's over here right still goes into slash games like this but it's going to be because the get is changed into the group that we created up here all right so for the second one we can remove games right it's just SL ID and same thing here a post is just is going to be like that for put it's going to be like this and for delete same idea all right so that's one way to avoid having to repeat the same name over and over again right that's that's what we know as a route group Builder Okay and then well let's make sure that things are still working properly so I'm going to just run the API and let's just check that we can go ahead and engage that HTTP we should be able to list all of our games so let's send a request so yeah that seem working just fine and I'm going to just test one more think our post right click Send request and it is working as expected right so it's all good awesome now the next thing that we should work on is well what happens if we receive invalid inputs right so in this case like for instance in the post case this one over here what happens if somebody posts um a payload with without a required element right for instance we should not be able to send and let me scroll down here we should not be able to post again without a name right so you should always have a name what happens if I just do this and send it like this we're going to try that out let me see yeah so my server is running and so well let's right click let's hit send request and let's see what happens right so notice this so the resource got created so 2011 no problem but now not notice this we got a null in the name so the API allowed us to just create an invited resource and that is not good so in this case what we should be returning is really a bad request right uh because it is a validation error and the input is not correct so we have to do something to account for those cases right so let's close this and let's see what we can do so let's go back and this time we can just close for MCS and let's focus on games end points now if you go down into my post over here right uh well there's a couple of ways to deal with this right I think I think the the the manual world to manual way to do this is well uh as soon as we receive the post request we could Su something like well if uh stream. is n or mty perhaps uh new game. name right uh we could go ahead and say well return we can do results. bad request right and perhaps we can even add a a little message here that says name is required right so that would be the basics that that you can do if we execute this I mean that should certainly work uh okay so we're running let's go back to G at http click here send request and that works right so now we are getting a bad request which is much better and we even have a little message down there so that's okay however of course uh this is going to start becoming a little bit uh challenging right because uh if we let's go ahead and stop the server server go back to games endpoints uh because name is not the only property right we have a bunch of properties here to deal with that could have many different kinds of validations that we need to perform in there so we're going to end up writing a lot of code here um perhaps we we even have to do the same thing for the put request right so this is not the best approach so what we want to do is to introduce some sort of proper validation uh into our dto and there are a few ways to do that so here I'm going to show you the simplest and and most basic when way that you can use in net to do validation and that is by using data annotations so let's H let's actually undo this we're not going to be using this really right and let's go back into shift e or Explorer let's go into create game DTU here's our dto class so we can do here is to use this concept of data notations so data notations are nothing more than just attributes that you can apply to your properties and that can Define what is expected of these properties for instance for the name we can Define here that the name is required right the name is required I'm going to do this control dot here to import the system component model that data an notations name space and even more I'm going to say that uh our name should not be really that big let's say that our name should be at much let's say 50 characters right not nothing more than that so we can do string length of 50 like that okay so with that any anywhere we use this great game dto that validation should be automatically applied that's the idea behind this okay and then um for the gener let's do something similar but let's do perhaps gener doesn't have to be that long perhaps only 20 that will be good enough and then for the price well price is not a string uh but perhaps we don't want to accept prices of I don't know thousands or millions or even more than that perhaps we can say that the price should be in a range of one to 100 that should be good enough for a price we don't have video games that are more than $100 um of price I mean that would be that would be crazy um and yeah that's pretty much it so that defines the data notations for our H for the creation of our right and this is remember cre GTO is the one that we receive here in the post however that's not going to be quite enough right if we just go ahead and run this okay run that and we go into g. HTTP if we go ahead and now run this H post request request it still is not doing the validation right so notice that we still get created we still got a n there so is not working uh so those data anotations will work just fine in the in the older core MBC framework but when you do minimal apis you need a little bit of more support and at this point what you want to do is to use a new feature called endpoint filters endpoint filters is a feature that comes with minimal apis that allows you to validate what's coming in into your into your endpoint and do some sort of validations around it right now and let me let me just close this and let me stop my Ser now we could use endpoint filters manually ourselves uh but there's Act a better way so there are nuget packages that already wrap the right endpoint filters that can tie directly into the data notations that we're using here so that we can easily enforce these validations right so what I want to do is to show you a nugget package that you can use to automatically perform the validation so let's let's actually go into let's go into nuget.org and by the way if you're not familiar with nouet nugget is the is pretty much the package manager for net and so there are hundreds and hundreds probably Millions well thousands or millions of n packages are already available that can simplify many things for you so you don't have to write your code manually so in this case we're looking for a very specific um nouet package let me show you here so I'm going just type here minimal apis. extensions you search for that this is a free nugget package well everything is free really here uh open source nugget package that is able to help us in this case so I'm going to grab the latest version here I'm going to just copy the command here for net CLI copy that and let's go back into vco so I'm going to open my terminal and I'm going to just paste that line so package minimum API extensions in this case I'm using version 0.11.0 and hit enter all right and so at this point if we take a quick look at our let's see gam store. API project this is our project file CS BR notice that now we have our first package reference this means that now our project is able to use any of the types classes defined inside that net package and because of that we can do the following now so let me go into G endpoints now under our post over here we can go ahead and say just before ending we can say dot with parameter validation which is one of the methods provided by that n package okay and just by doing this the appropriate endpoint filters are going to be applied and are going to recognize this data annotation that we specified in great game video so now if we just go ahead and uh run our API okay it is running back to games at HTTP let's execute our incomplete request send request and notice that not only we get our bad request as we should uh we even have a nice error message down here so let me show you uh nice error message that says okay so one or more validation errors occured we have a status 400 and we it even tells us exactly which field uh is missing right and so and this is this is very nice and in fact this is actually tied to the proper RFC that you can see over here uh which is the right way the standardized way to report errors back into clients so that clients can easily read these errors and act accordingly right and we were able to do all this just by using one nouet package right now if we go back into the code uh one thing that you should realize is that um you can can do this parameter validation not just for one endpoint you can actually apply it for all of the endpoints all of the endpoints by using your grout route group right remember that we have a group here this group over there so what you can do now is just say um actually we can just change it here we can say dot with parameter validation and now these validations apply to any of the endpoints that are going to be receiving one of these uh DS that have data notations right and in fact we are doing validations right now for create G dto but we should do the same for our updates right our they should also be validated so let's open up update game DTS dto and then well I'm just going to go ahead and and copy this because it's pretty much the same validation we're going to apply right there same validations and make sure that we import the right in space and now both create and update should get validated so let's go ahead and run our API let's make sure that all of these validations are working properly right so let's go back into G http so we already verified H the create for an empty name now what happens if we try to do a very long name right so Minecraft Minecraft Minecraft big name like that so I'm going to right click here send request okay let's see notice the error now the field name must be a string with a Max a maximum length of 50 right so the length is getting validated for that request which is is correct right let's uh let's go back to to this uh what happens if we have a uh if we don't have a generate let's see right click and then send request yeah the gener field is required so that's good and let's do something about the price right we said that the price should be at much 100 so let's see if you try a price of 119.99 right click Send request and as you can see over here the field price must be between one and 100 so that's all working just fine and lastly let's go ahead and verify that our put is also validating right so let's remove the G the name from the put and let's use a valid a ID let's do id2 right click and request and as you can see once again we get a bad request my request over here and uh if you go down there yeah you can see the name field is required so yep it's all working as expected so now we have properly validated endpoints all right so let me go ahead and just stop our server okay and uh with this in place I think it is time to start moving away from this ink memory list of resources and actually introduce a proper database for our res API and to do that we're going to be using a very handy framework that is part of net that is known as Entity framework core so let's switch briefly into slides to learn more about Ed framework core and why it's going to be super useful for our development here in this section you will learn about the object relational mapping technique and how Entity framework core can help you write code that interacts with your database without having to learn a new language at this point we want to add database support to our res API so that all our data is persisted beyond the lifetime of the application so whenever a request to create a game is received in our API we want to create that game in the database and when the client requests a list of games we want to query that list also from the database however there is a problem the database does not speak the same language as your esinet core API your API is coded in C but your relational database server only understands the SQL language that means that to fulfill that request to retrieve games your C code needs to translate the API request into a carefully crafted SQL query and then send that query to the database server the database server executes the query and then your C code has to read back any resulting rows and translate them into a corresponding API response this presents a few problems as a c developer you now need to learn a completely new language SQL in order to graft the required queries and you need to learn it well to to ensure you get good performance out of it you'll need to write a lot of additional data access code whose only purpose is to translate things from C to SQL and vice versa and of course deal with unexpected errors talking about errors this approach is error prone since it's very easy to make mistakes when mapping things from one side to the other and you need to manually keep your C models in sync with the corresponding database tables which can be quite challenging this is where object relational mapping techniques or orm can make a big difference but what is orm well going back to our Spotify example imagine your application has been created using an objectoriented paradig and therefore it includes objects to represent songs artists and playlists and if you're working with a relational database server there's a good chance your database will have corresponding tables for each of those objects now instead of having to write custom code to map these objects to tables each time you need to send or receive data to or from the database you can set up a map between them so that your program can keep working with objects while another component an object relational mapper takes care of transforming objects to tables and vice versa so in essence object relational mapping is a technique for converting data between a relational database and an objectoriented program and as you can imagine it brings many benefits to application developers and fortunately snet core includes a great orm framework called Entity framework core so what is Entity framework core it is a lightweight extensible open source and crossplatform object relational mapper for.net Entity framework core will sit between your res API and your database server besides mapping your donet objects to database tables it will translate your C data access code into seq statements that the databas server can understand and it will also translate any resulting data from the database into objects that your API can easily manage using Entity framework core in yournet applications brings in multiple benefits there's no need for you to learn a new language you can perform all data access tasks using your familiar C language the actual data access code that you need to write is minimal since Entity framework takes care of most of it in fact you can use language integrated query or link to perform most of your database queries there's tooling available to keep your C models in sync with your database tables so you don't need to do this manually anymore Entity framework can keep track of the changes made to your C object instances at run time so it knows what changes to send to the database when it's time to persist the data also Entity framework cor supports multiple database providers so you can use your same C models with other relational databases if needed let's now see how to use Entity framework core to add database support to our game store R API the first step towards adding database support into our API is to define the class or classes that are going to represent the data model model of our application now could we just go ahead and use our dtos for that um you could try to do that but in general that's really a bad idea remember that the dtos represent the contract between your API and the clients right and that should rarely change however what we want to Define now is the data model so this ties directly into the database tables that we're going to be using in in our database and we want to have the flexibility to change those tables and to lay them out in a relational structor that may not match those contracts those DS that we have already defined okay so because of that and to have this flexibility we want to keep those separate right so let's not touch the dto at this point and instead let's go ahead and in our solution Explorer let's create a brand new directory which we're going to name a new folder is going to be entities okay the entities are going to represent our data model and then let's right click click on entities and let's add a brand new file and this is going to be a class and this first class is going to represent not our gains but actually our game generous because in our database we don't want to just store simple strings for every single game right for sports racing and all that uh we want to have a proper table where with all of the game generous and then have a relation between our games and our generes so let's define first our gener table for our gener entity right there okay and for this class let me collapse this for a bit right there for this class first let's go ahead and fix our name space as usual like that we're going to have just two properties here so we're going to do prop and then this is going to be an INT is going to be the ID and this the second one is going to be string the name now we do have a small warning here right for name that says notable property name must contain a nonn value when exiting the Constructor what this means is that we have declared a variable that is not nullable right it's a simple string not nullable string and yet we have not defined any default value for this for this property right and so the compiler is complaining about this and it's asking us to to provide either provide some value or declare the Val the variable as n so there's a few ways to fix this you could start by just doing like something like this if you wanted to that will initialize the variable as an empty string another way to do it would be to say Okay so this actually going to be a nullable string like that uh but we don't really want to have H nules in our G names right so a better way to do this is by actually using the required keyword over here required and by doing that you're saying that whoever goes ahead and constructs instances of gener we have to make sure that they provide a value for name when they construct the object right whichever way they use to constru the object they have to provide a value for name right so that's a very handy way to deal with new lables incision right so now that we have a class for the generate we have to Define another entity in this case for the game so let's right click again on entities new file class and this is going to be our game okay once again let's fix name space like that and let's go ahead and define the properties for our game so if you remember we should have here an ID then we should have our name so this is going to be our name and same thing we want to define the name as required just like this it's required scroll down a little bit and then we need to define the generate but now as you know we are going to be using a relational model to associate the game with the gener uh because of that we're going to have to do two things the first thing is that we need to Define uh a a property to represent the ID of that gener that's associ to the game so what you can do is just say generate ID okay so this is the ID that is going to be connected to the ID of generate in the gener entity but we also have to specify another property here of the type of gener itself so it's going to be prop type generate and I just call it gener now this property here may or may not be null right depending on if we decide to populate generate when we read data from the database via at framework we may decide to populate generate or not right sometimes it may be just enough to have the gener ID so that will be populated but not the gener so since it's not clear at this point if we are going to have for sure a value all the time so we can totally go ahead and just declare this as a n just like that okay sometimes we have it sometimes we will not have it okay so that this combination of two properties is what you do on Entity framework when you want to do an Association in this case a onet to one relationship between game and gend right and so let's scroll down a little bit more and then let's go for our price which we know it is decimal that's a price and lastly let's go forour date only release date and with that we have defined the two entities that represent our data model now it is time to add proper Entity framework support into our API and for that we're going to be needing a nuget package so let's go into nuget.org over here okay and we're going to be looking for a brand new nugget package so let's search for microsoft. entityframework cord. SQ light so SQ light is the database engine that we'll be using uh for this tutorial okay it's going to be the first hit over here and keep in mind that you could be using really any other relational database here like SQL Server if you wanted to but but for this tutorial I'm keeping it very simple with SQ light is the one that lets you get started very quickly but most of the code that you're going to see me writing from here on is going to apply the same way to other relational databases like SQL Server the only thing that changes really is what provider you use for Entity framework in this case we're going to be using the SQ provider if you wanted to use SQL Server you can just change SQ for SQL Server right and now you have a provider for SQL Server all right now this case let's go for sq8 and I'm going to copy not the 900 preview let's go for a stable version in this case I'm selecting 8 802 I'm going to copy this let's go back into our code okay and let's just paste. net package this micros framework cod. sqlite version 802 all right so now our API is ready to take advantage of Entity framework now let's close this terminal and let's close close this so let's go back into our solution Explorer in this case and what we're going to do is create a brand new directory to store any of our data related classes so let's right click on game store. API new folder let's name this one data and then in our new data directory let's go ahead and right click we're going to be adding a brand new file it's going to be a class and this class is going to be what is known as a DB context uh now in this case let's go ahead and name it game store context right gain store context let's collapse this and let's just fix our name space very quickly change name space to gain store. API that now G store context should inedit from DB context DB context okay now notice that uh this imported Microsoft Entity framework core this is a new imported name space uh but well you may be wondering well what is a d context right so D context is really an object that represents a session with the database and that can be used to query and save instances of your entities right so this is the intermediary so if you're familiar with either the repository or the unit of work patterns um the DV context is a combination of both unit of work and repository right now to properly construct your G your DB context you're expected to receive here you should receive what is known as DB context options so DB context options of the type of your DB context in this case game store context right let's just name these options okay and let's send this to the next line let's send over those options to the base Constructor like that so those options are the ones that are going to provide the gain store context all of the details about how to connect to the actual database all right now the next thing that we're going to need in our game store context is some sort of representation of the objects that need to be mapped into our database right and so we know we're going to Beal with games and with game generes right so because of that we're going to do the following we're going to declare prop and it's going to be of type DB set so DB set of type of the actual entity here so it's going to be game that's entity and we can name this one games okay now what is a d set well a d set is really an object that can be used to query and save instances in this case of game so any link queries a language integrated query queries uh against a d set in this case of type game will be translated into queries against dat right and to provide an initial value for for games what we can do instead of this is just point directly into H we can use this method set of type game okay that's going to create our DB set instance all right and just like this one we're going to create another one dbet of type J and let's name it gems which is going to point to a set of type G our context is ready to go ahead and map our objects our entities into proper database Tes but what we have to do now is to tell our application how to connect to the database to our cite database using this gain store context and for that we have to register the context on start app so let's go ahead and go back into our Explorer view over here and let's go into pram CS over there pram CS and here's where we have to start using our Builder object to register Services right so down here what we can do is the following first let's go ahead and Define a connection string so let's just name it Con string it's going to be so how do we actually connect to sq light so it's actually super simple this is why what I really like sqlite all you have to do is specify here data source equals and here you specify the physical PAAD into your database file right so in this case let's just call it gam store. DB okay now here you could specify some other pad in G store. DV if you don't want to have it directly um at the root of your project uh but for the cases for the case of this tutorial I think it's just fine to have it directly under the the project directory right but you can specify really any other physical pad so yeah that's a connection string and with that connection string we can go ahead and actually register the service and to do that what you want to do is you say builder. services and then in this case add SQ light and here we want to specify the name of our context the one that we just created so game store context and then we want to pass in the connection string okay now this is taking advantage of a mechanism that is known as dependen injection which we're going to be talking about later in the tutorial uh but important thing to know is that because we are adding this Services here Entity framework is going to take care of reading this connection string right and then it is going to create an instance of our gain store context and it's going to pass in DB context options over here that are going to contain all of the details that are in that connection string so that it can connect to our database right and map the entities to tables however there's one thing that's not really ideal here and that is that we have the connection string right here in the code right now in this case it is SQ the has nothing really wrong there I mean there's no secrets no credentials it is incredibly simple that is fine however it's still not really great to have the code for the connection string right here because as you change into another environment let's say into a production environment you're going to have to change your code here right to point to an actual production database and that's just not idea so you want to keep this information this configuration data outside of the order code base so to understand where we should be putting this connection string let's go ahead and back into the slides to understand more about the AET core configuration system at this point we have hardcoded the connection string to talk to our database directly in our application code however this is not ideal since eventually when we move the API to a different environment like in a cloud deployment the connection string will be different and we would need to make code changes which is not ideal fortunately there are better places to store application configuration one of the most popular options in hnet core especially for local development is the absen Json file which can store all sorts of configuration information in Json format now the absens the Json file is what is known as a configuration source and just like that one there are several other configuration sources supported in net applications like command line arguments environment variables user secrets and even cloud-based configuration sources like Azure key volt and the great thing about this is that the SB net core runtime takes care of combining information from all available configuration sources into a single configuration object that implements the ey configuration interface this configuration object is easily accessible to your res API in such a way that it doesn't really need to know where the configuration data actually comes from in this tutorial you will use the apps Json file to store your connection string but keep in mind that this is an acceptable option only because you don't need to use any credentials to connect to your SQ light database if for local development purposes you are using a database server instance that requires credentials please use the user secret configuration Source instead which is enabled by the snet cord secret manager never restore any kind of credential in your appsetting Json file let's now update our res API to read the connection string from the appsetting at Json file let's see how to take our connection string out of program.cs and into our upset. Json file so let's go ahead and open ups. Json and what we want to do here is to introduce a brand new section that we're going to name connection strings now this very specific element called connection strings is a well-known element of net meaning that there are apis that are going to be looking specifically for this one word here Nam connection strings so make sure that you type connection strings just like I'm doing right now now inside this element you can introduce one key for each of the connection strings that you want to introduce into your code now in this case we want one connection string for our game store database so I'm going to just type here game store you can really type any name here but just make sure that is something that's related to your database okay and then on the right side we want to introduce the actual value for this key now what value we're going to use let's just go to pam. Cs and copy the connection string that we have been using so far okay and then let's paste that over here all right so now the connection string is outside of our code and we go back into prom Cs and like I said there are apis specifically designed to read these connection strings and let me collapse this for a moment and what we can do now instead of just H reading the hardcoded word is use the Builder object to get access to the configuration object over here which is the one that implements I configuration and is the one that collects configuration information for every single configuration search that has been configured for your application like I mentioned in the previous lesson in this case this is going to include our upside adjon file and because of that we can just say get connection string then we pass in the name of the key of our connection string so in this case case in say that Json we remember that that is game store so I'm going to copy game store and I'm going to paste that over here all right and that's really all you have to do to read your a connection string fromjson now let's confirm that this is actually working by placing a break point over here perhaps in l seven to see what value we read into connection into const string so with that done I'm just going to go ahead and press F5 to start a debuging session so F5 and this should be one of the first lines that is hit AS application starts all right so breakpoint has been hit and so let's see what value we have ofation string as you can see data source equals. DV is exactly the value that is being read from our set the Json file all right so that is working perfectly which is great so let's just stop this session now at this point our application is pretty much ready to talk to our database however the database itself this sqi database does not exist just yet we need to go ahead and create it and to do that we can use a process that is known as migrations so this is the Entity framework process that takes the different entities that make up your data model and turns them into corresponding tables in your database that are properly mapped to those objects and before we can do that we're going to need to install when additional tool so let's go back into our nugget page over here and let's look for a tool called net EF okay this is going to be the first hereit over here so netf is a tool that you can use to do all sorts of Entity framework related task against your application now in this case I'm going to pick version 8.0.2 which is the latest stable version at the time that I'm recording this so I'm going to just copy this command and let's go down here vs code let's open our terminal let's switch to gam store. API and let's just paste that command okay so this line here is going to install netf this is not just a nuget package it is an actual tool that you can use to execute a the frame related commands so I'm going to hit enter notice that this also installs a tool as a global tool right that's why we using Global over here meaning that you can now use it from any net application that you have in your machine now the next thing that we're going to need is an additional nugget package and so let's go back into nuget gallery and let's look for this package called microsoft. Entity Framework core. design now this package here is the one that is going to be used to actually generate our enti framework migrations so let's go down here let's pick our latest stable version 8.0.2 I'll copy this and back into BS code I'm just going to paste that here hit enter and the package is now installed in our API project right let's close this so now we're ready to generate our first migration now we have to decide where we're going to to generate this migration if we look at our Explorer over here what we want to do is just to generate a folder under our data directory we're going to place a new folder which is going to contain our migration which is going to have all of these mapping code between our our C code in and database right so to do that let's go ahead and open up our terminal once again going to clean this and perhaps let me expand this a bit more so we can see better so make sure that you are in the gam store. API directory this over here and then you can execute the following command you can do netf migrations at initial create you can use any name here this is just the name for the migration that we're created since it is the very first migration I like to call it just initial create but you can use any other name and then we're going to give it the output here it's going to be under data like we said the data directory and then under that directory let's create another one called migrations all right let's go ahead and execute this okay like I said it is built and then the migrations execute now what actually happened here so if we go back into our Explorer let's close this now we should have under data as you can see now we have a brand new migrations directory over there open up that and you're going to see a few new files I'm going to go into all the details of these files but one thing that we can take a look at is this very first file initial create notice that this is going to have kind of um of number that is somehow related to the date and time that we are generating this migration on right and so if I click on this file let's see what we have here so as you can see so this is a class that extends from migration it's called initial create and this going to have uh this the following methods so first is going to have this up method which is the one that is used to move to the next H migration that the database is missing right so this is known as the up method then but we also going to have a down method that could be use it to go back to the previous state of the database now if we go back into our up method notice that here is where the actual tables are going to be created right so migration Builder create table here is the name of the table generous right because our DB context defines this generous D set then generous is going to be created as a table and here are the columns for the table right which are going to be created in the context or in the terms of the database server that we're are using in this case we're using SQ light so because of that it is creating a table with a type integer in the for the ID column and then with a type text for the name column right it also sets up a primary key for the for the ID field in the generous table and then we move on into the other table the games table over here that defines an ID name General ID price and release date right with corresponding values for each column notice also the the ID is is going to be an AO incrementing column meaning that anytime we insert a value into this table uh a brand new number sequential number is going to be assigned for the ID okay then we also have our constraints here we have a primary key for the games table on the ID column and we also have a foreign key that relates our games table to the ID column in our generate table that means that every every ID that we use for Generate ID in our gam table has to exist in the gener St all right that's a foreign key constraint lastly we are creating an index for the generate Ed column in the gam table all right and like I said in down what's going to happen if we decide to go back into a previous version of the database uh it's going to just go ahead and drop the gain table and then it drops the generous table in the proper order all right so yeah so that is the migrations process and now our codebase is ready I mean the codebase now knows how to go from nothing and into the actual database so what we have to do now is to execute this migration so that it it's getting it gets applied into the database so let's see how to do that let me close this and this and and let's go ahead and open our terminal here let's clean this and really all you have to do to execute the migration is to use again netf and in this case the command is going to be database update so let's hit enter so net Entity framework is going to locate that migration code and it's going to execute it against our machine right away so let's take a quick look at what's going on here so you're going to see a bunch of Entity framework related commands but you can see how the table gets a gets the tables get created now the first table as you can see here in this in this section here is the EF migration history table so this is a table that's going to be used to keep track of what's of what's migration migrations have already been applied into your database right that's how Entity framework knows what is missing from your database if you add new migrations later right so that's the E migration history table now if we keep going down we're going to see that here's where Entity framework Noti it that we have to go ahead and apply this BR new migration that we created that's what's going on here and then later it goes ahead and creates the gner table as you can see creates G table and then we keep going down and we will go ahead and create our games table right here right and then it will end up creating the indexes and finally it sets a brand new value into EF migration history for the brand new migration that we just execute right so that happened seems like it was a success now how can we actually take a look at that database and make sure that it got actually created right so let's go back to our Explorer view over here and one thing that we we going to notice now is that we have a brand new gang store. DB file over there right now the reason while this file which is a file for our sqli database got created directly under our game store API directory uh is because of how we Define our connection string right if we go back to abs. Json I'm going to close this remember that we said that the file would be just in gam store. DV which mapped directly into the root of our project now if you wanted to uh I mean you could move this file somewhere else like for instance you could do something like I want to have a DV deer like like that and that will create a that would place a database into that DV deer under your proct directory uh but just make sure that uh I'll be aware that you have to create this directory manually before doing that uh otherwise entity will not be able to create your database right now since this just for local development I think it's just fine to keep the databas like this but one thing you may want to do if you're using git for instance is to make sure that you exclude this file from your git comit right in on Gore so that the file does not get checked in right so now we have our H file over here but how do we actually get into it now remember that we installed this skite extension for BS Cod that means that we have the ability to pick into that database and to do that let's just right click in game store. DV and let's use this very first element over there that says open database click on that and by doing that notice that a brand new Explorer showed up over there on the left side SQ Explorer so that is going to allow us to start looking into what's going on in the database and if we start expanding these notes here we're going to see the structure of the table right so we have generous with an idea and a name and then we have games over here with an ID name gener price and release date there um lastly we also have like I mentioned we have our EF migrations history table right there which like I said this is the one that keeps track of every single migration that we are executing against the database now if you just right click cck on the EF migrations and we select show table that's going to show us the current set of values inside that table as you can see this just one value over there and it even keeps track of the version of Entity framework that we're using so far all right so yeah so our our database now exists and our application is ready to start start working with it now let's go ahead and close this and let's go back into our file explorer now one thing that I like to do to simplify things a bit is to have a little bit of code on Startup that takes care of applying any missing migrations when the application starts that way we don't have to run the Entity framework command to update the database every single time that we add new migrations so let me show you how to add some some of this code so that the migration just happens as soon as as application starts all right so on our data deer and let me actually switch into solution Explorer now under our data deer I'm going to right click and add a brand new file okay it's going to be a class and this one let's name it just data extensions okay so this is going to be an um an static class to hold a brand new extension method so let me let me now collapse this oops let's just go back to the file right here okay so let's fix our namespace contol dot let's fix it to gamestore api. dat like I said this is going to be a static class because we want to put an extension method here and let's introduce a brand new method here that we're going to name going to be static because it is extension method migrate DB okay and this method is going to extend the web application object application class all right and what we want to do here is to go ahead and migrate the database so there are API in the framework to go ahead and migrate your database however everything that has to do with our database needs to have an sculped Lifetime and we're going to be talking about dependence injection and these lifetimes in in a moment uh but for now what we need to know is that we cannot just access the DV context directly we need to provision a scope that allows us to actually start interacting with the database right so let me show you how to do that first we're going to be getting an instance of a scope so to do that let's do this using bar scope equals uh services. creat scope right so that gives us a scope and let's see what type is is this is an i Services scope right that we can use to request the service container of ainet cord to give us an instance of some of the services that have been registered in the application now remember if you go back into program. CS over here pram CS we have executed this line here right at SQ light this this line here is going to register our game store context in the service container right meaning that aset core knows about the type and is ready to provide us an instance whenever we request one right so if you go back into the extension what we can do is the following we can now say d context equals scope service provider. get required service what service we need we need the game store context service Okay and like I said we're going to be talking about about more about this dependency injection and services codes uh in a moment uh but for now let's just use our DB context to get access to our database and from there we can access the migrate method over here which by the way imported a brand new namespace at the top over there Microsoft Entity framework core all right and with these few lines we are now ready to execute migration on Startup now all we have to do is go back into PR Cs and invoke that method so I'm going to do that actually close to the end just after map game end points I'm going to just say app. migrate DB right we can use this method because it extends our web application uh object over there all right now to verify that this actually works what I like to do is just to well delete the database right delete the database and the application when it starts it should go ahead and recreate the database automatic right this is one of the reasons why I like to use SQ light for learning purposes because it's very easy to use right click on the V here and delete the database right yep delete it's gone okay now let's go back into our terminal over here going to clean this and I'm going to go ahead and do net run and let's see what happens as you can see all of the all of the statements uh go ahead and perform the migration executed as you can see over here all of the statements executed just before stting the application and gam store. DV is right there regenerated all right so yeah that work just fine and simplifies a little bit the way that we execute these migrations now one thing that I don't don't like and let me just stop my server for a moment is having so many statements every time the application starts right because from here on any time the application starts Entity framework is going to be logging whatever is doing to our database if needed so one thing that we can do is to uh simplify a little with these logs right so we don't have to see so much right it is fine if we need to but login can get very BOS so how do we actually switch this loging a little bit so that we don't have to see so much every time it starts so let me cross this let's go into absence. Json over here and what we can do is to um add just one more entry into this section login which is the one that configures login for our application we can add one more entry to change the login severity of one of the elements of our application so for instance in this case if we go back into the terminal right for instance all of these statements that says hey I'm executing this command here and this command there right uh this I think that's just T BS like all also here but all of those statements are coming from this one name space look at this Microsoft Entity framework code. database. command so we can say we can do is say hey uh for anything that comes out of the Microsoft framework code. database. commanding space please only show me warnings or errors right or something critical but do not show me just information messages right these are all info as you can see on the left side these are all informational messages what I'm going to do is just copy this let's see if we can copy close this and I'm going to add an entry into here to configure a different lock level for that very specific name space right I'm going to say that for this one one I do want to use War okay and by doing that I'm saying hey I only want to see either warnings or errors or something critical but not anything that is really less severity than that okay so if you now go back into the terminal and let me actually open my Explorer I'm going to delete the database once again let's see what happens different this time so I close this let's clean our screen and let's do net run notice that now the output that we got here is is way different right there is no mention of all of these commands that are executing in there all that we are going to see here is this line here that says applying migration something something and then if there was any problem with that migration or with any of the commands it would show up here uh but otherwise the console it is just very clean right there's not much going on there so doing this is something optional I mean if you want to see all those commands every time H just feel free to not and not do what we just did in ABS Json I just like to keep our command line as clean as possible all right so let's stop our server and go back to our code just close of that and let's go back to our file explorer now as you know we have this concept of game categories in our application right so things like sports racing or playing and all that and for those values that are which which are pretty much fixed across the application we're not going to be creating apis to to create or modify the categories we're just going to go ahead and populate the categories when the application starts right and to do that we can use a very simple process of data seating that we can introduce directly into our game context or game store context object so let me show you how to do that let's go into our data directory and into our game store context over here and what we're going to do if we scroll down a bit is to add a brand new method just under our latest DB set and let's let's go ahead and overwrite we want to overwrite the on model creating method this one over here on model creating all right so let's scroll down and this is one of the methods that going to be executed as soon as the migration is executed right so when you execute the migration this code over here is going to execute so this is an opportunity for us to do things that slightly modify the model according to our needs and one of the things that we can do here is to populate some very static data right now I'm not going to I would not do this for data that requires much more complex operations right this is just for some some things that are very very simple and like I said this is just a list of categories now to do this what you have to do is just say model builder. entity and then the type of entity is generate and then we're going to be using the method called has data right so this is going to make sure that whatever data we introduce here has to exist when the migration process completes okay now here what you want to do is to introduce well as many elements as you need for in this case for the gener so for instance I can say new and then I'm going to say well ID equals one and this is going to be our name equals and the first category is going to be let's say fighting all right so there we have our first element and let's go ahead and spin up a few more categories I'm not going to just type all of them let me grab them from my other screen here now we have um five categories that we can work with right so fighting roll playing sports racing kids and family feel free to use less or more of this as as you want but yeah so just by having this code here all of these H these five categories are going to be created as the the migration executes so now for that to work we of course need to add a brand new migration right because otherwise Entity framework doesn't know that it needs to map these to the database so to do that let's go ahead and open up our terminal and let's let's add a new migration so net EF migrations add and now we want to use a new name for this migration so let's say seat JIS all right and once again the output output here is going to be under data migrations right let's go ahead and hit enter all right migration completed let's see what happened on our Explorer over here migrations now we should have a brand new file so you can see we have C generous right here C generous let's click on that one let's see what happened over there now here we have a brand new up method so here's up and then here the migration Builder is executing the insert data method over there to go ahead and into the generous table is going to insert these five values all right so that's that's all we have to do and for the down method you will go ahead and delete all of those values that you got inserted all right and once again like I mentioned I would only do this for very very simple data that does not need to interact with any other objects in the application because remember that you're not actually running the application at this point you're just doing some static work as you're applying the migration right so only for very simple stuff and static data that is not going to really change so if we go ahead and run the application now right so net run run application okay notice that the new migration got applied over there see generous got applied and if we go into our database okay let's collapse this let's go into our gam store. DB actually SQ Explorer if we go ahead and right click on generous I'll say show table let's see what we have let me collapse this let me close that and that as you can see here we have our five generates now as part of the actual tape right so they're right there is live data that we can now use in our application all right so that is complete let me go ahead and just stop my server now we are approaching the moment where we actually need to start changing our res API to take advantage of our new DV context and all this Entity framework stuff but before we can do that it is very important to understand this concept of dependency injection because remember for MCS we are using dependence injection to register this the the game store content into ainet core but what does that registration means and what is all of this depend injection concept about so let's switch to slides so we can better understand the concept of dependen injection in this section you'll learn about the dependen injection design pattern and the multiple benefits it brings in to your applications to understand what the pendis injection is let's start by looking at two classes my service and my logger my service uses the log this method meod of my logger to log messages to a file anytime my service performs an important operation since my service uses some of the functionalities of my logger like the log this method we say that my logger is a dependency of my service now in order for my service to start using my logger it creates an instance of my logger in his Constructor and after that it can start calling the lock this method at first glance it doesn't look like this presents any problems but consider what happens when the authors of my logger decide to slightly modify it so that a new my file writer object needs to be passed on this Constructor because that's where the output file is now defined the required changes look simple to implement but they reveal a few important problems my service is tightly coupled to my logger in such a way that any any time my logger changes there's a need to also change my service as it happened here when the Constructor started requiring a my file writer instance my service needs to know how to construct and configure the my loger dependency like is the case here with the my file writer object which needs to be configured with an appropriate file to send the output lcks this makes it hard to test my service since unit tests won't be able to mod or stop my logger an output. log file will always be created which would slow down tests and this assuming that the test have access to a place to write files to fortunately there's a better way to do this using what is known as dependency injection let's go back to my service and it's my logger dependency my service it still uses the log this method but this time my logger is not explicitly constructed by my service instead my logger is passed in as a Constructor parameter my logger is injected into the my service Constructor this way my service doesn't need to know how to construct or configure the logger it just receives it and can start using it right away but if my service doesn't construct the logger who does it well snet core provides the I service provider which is what is known as the service container your application can register my logger and any other dependencies with I service provider during starup which is typically done in your program.cs file then later when a new HTTP request arrives and your web app needs an instance of my service the service container will notice its dependencies and it will go ahead and resolve construct and inject those dependencies into a new instance of my service via its Constructor this enables multiple benefits for your application to start with my service won't be affected by changes to its dependencies it doesn't matter how many times the Constructor of my logger changes there is no need to change my service moreover my service won't be creating instances of my logger so it doesn't need to know how to construct or configure it if your application uses minimal apis dependencies can also be injected as parameters to your minimal API endpoints finally dependency injection opens the door to using dependency inversion but what is dependency inversion the dependence inversion principle states that code should depend on abstractions as opposed to concrete implementations let's bring again our my service class and it's my logger dependency currently my service depends directly on my loger which allows it to write logs to an output file but let's say that now we're moving to the cloud and we need to start sending logs to some sort of cloud service for this we would like my service to start using a new Cloud loger class we could modify my service to receive and use a cloud logger instance instead of a my logger instance however what we can do instead is modify my service so that it depends on a new ey logger interface instead which provides all the required login functionality then we can have both my logger and Cloud ER implement this new interface with this we are decoupling my service from the logger dependency allowing it to use my logger Cloud logger and any future logger implementations without ever having to modify my service the only thing that the different loggers need to do is to implement the interface that my service depends on in terms of the code this is how you would now inject the logger into my service so the main benefit of of using the dependency inversion principle is that dependencies can be swapped out without having to modify the class that uses them but also it is now much easier to test my service since the loger dependency can easily be mocked out or stopped and finally your code is now cleaner easier to modify and easier to reuse now before we start using the bend injection in our code there is one more important concept to understand which is the service lifetime we now know the basics of dependency injection in ESP core we know that on Star app your application will register the dependencies like my logger here and later when an HTTP request arrives I service provider will resolve construct and inject an instance of my logger into a new instance of your class my service in this example what is not clear is what happens when a new request comes in should I service provider create a brand new my logger instance for the new request or should it reuse the same instance what if another service that also has a dependency on my logger needs to be created in response to a new request sa my logger instance or new my logger instance the answer to this lies in the service lifetime which you configure when you register my logger with I service provider there are three available service lifetimes so let's take a look at each of them let's say that my logger is a very lightweight and stateless service so it's okay to create a new instance every single time any class needs it in that case you would register my logger with the at transient method when the first HTTP request arrives the I service provider as usual will resolve construct and inject a new instance of my logger into my service however when a new HTTP request arrives I service provider will construct and inject a brand new instance of my logger which has nothing to do with the first instance furthermore if there's any other service that participates in any of these HTTP requests and also has a dependency on my logger it will also receive a brand new instance of it so transing lifetime services are created each time they are requested from I service provider what if my logger is a class that keeps track of some sort of state that needs to be shared across multiple classes that participate in an HTP request in that case you would register my logger with the adcode method here when an HTTP request arrives the I service provider will again resolve construct and inject a new instance of my logger into my service but if there's any other service that participates in that same HTTP request and that also has a dependency on my logger it will receive the exact same instance of this dependency however if a new HTTP request arrives the service container will create and inject a brand new instance of my logger instead totally unrelated to the previous instance so esope lifetime services are created once per HTTP request and reused within that request finally let's say that my logger is not cheap to instantiate and it keeps track of a state that should be shared with all classes that requested during the entire lifetime of your application then you would register my logger with the at Singleton method as usual when an HTTP request arrives the I service provider will resolve construct and inject a new instance of my logger into my service and if there is any other service that participates in that same HTP request and that also has a dependency on my logger it will receive the exact same instance of this dependency but furthermore if a new HTTP request arrives the service container will once again provide the same instance of my logger to any of the classes that requested and it will keep doing so until the application is shut down so singletone lifetime services are created the first time they are requested and reused across the application lifetime now that you understand the benden injection in h net core and the different service lifetimes let's get back to the code and see how we can use these Concepts to use a DB context across our API endpoints we just learned about the Bendis injection and service lifetimes but how are those related to our DB context well going back to pr. CS let's look at this line here line seven builder. services. atsq light with gamore context this line is actually registering our DB context gam store context into the service provider which is a service container and it is doing so with an scope lifetime so it may not be may not be evident here but when you see this line what's really happening under need at some point is something like builder. services. add scoped with game store context right and there's of course more going on than than just this but this is the key part so gamar context is getting registered with the service provider so that later on anywhere in our code base we can go ahead and inject that instance of gain store context into our code so that we can take advantage of its services now why why is this gain store context registered with a scope Lifetime well by doing a scope lifetime this ensures that a new instance of the D context is created and dispos for every single request and this is important for a few reasons like for for instance database connections are limited and they are a relatively expensive resource so by having the DV context registered as a scov life time that ensures that the connections are opened and closed efficiently also DB context is not threat safe so having a single instance of the context across multiple requests would lead into concurrency issue so we don't want that we also have to think about transactions right so having a separate DB context instance per request makes it easier to manage transactions and ensure data consistency across a single unit of work without interference from multiple requests and finally reusing the same D context instance across multiple request could lead to increased memory usage because the DV context keeps track of changes to entities over its lifetime so by having a scope lifetime that ensures that the DV context is short lift and R reducing the memory overhead and potentially improving performance all right so now that we understand that our gam store context is getting registered as a scope service we can start taking advantage of it across our code base okay so let's let's go ahead and remove this line and let's put this as it was and what we can do now is go back into our end points so end points over here games end points all right let's collapse this and close that and we can now go back into our post empo let's start with post this one over here which is the one that's going to allow us to create a brand new game so as you remember the only thing that we're receiving right now in the Handler for this method is the the dto the new game dto so now we're going to go ahead and inject the instance of gain store context that has been registered in the service provider so for that all we have to do is just add gam store context DB context all right so at WR time a minut court is going to take care of of resolving and providing us an instance of that context right here without us having to do anything else and so from here on we don't need to be creating uh these DTS manually as we're doing it here instead what we want to do is to start creating entities into our DB context so here's what I'm going to do so I'm going to say it's going to be just of type game equals new okay and now I'm going to do control do here so we can import our Gam store. api. entity Nam space all right and here is where we're going to be declaring all of the properties of our brand new game okay and let's start with the name so name is going to be new game. name and the next one is going to be the gener right so we want to assign a gener here now the problem is that if we go into new game do we're going to notice that currently the gener that we have in this new game in this D and I'm going to do F12 or here on J to see once again the definition of our create game dto the problem that we have is that gener is just so far a string but this is no longer going to really play well with our scenario because think about it our client is likely not going to send us the string corresponding to the generate likely the client will will send us the ID the unique identifier of this generate so we can create it into our data model right but so far this is just a string so we need to change our dto at this point so that we can receive the proper ID of the let's go ahead and change this right so let's go and do generate ID all right and with that let's go back to games endpoints and now we can actually assign a gener to the game now what gener will be assigned because this is this is an actual entity right so to do that what we're going to do is just say d context that gener that find and we're going to say new game. gender ID right so with that we are actually taking advantage of the D context to find the instance of generate that matches that gener and then we're going to assign that into a generate IND The Entity but also remember that we also have a generate ID property in game itself so we should also assign this to new game. generated right and then let's just go with the price which is you g the price and finally the release date which is new game. relate okay so that is the creation of our entity and then we have to go ahead and uh add this brand new entity into our DB context and to do that we can do DB context. games the games D set and then you can say just add and then we will put here the game right that's what you have to do to add it to the D context so that Entity framework and the DV context can start keeping track of this brand new entity that will need to be stored into the database another way to do this could be to just remove games and just say that add that should work too but I prefer to use games just to be a bit more explicit to tell where exactly this game entity is going to go lastly what you also have to do is just say DB context do save changes right save changes is the method that's going to actually transform all of the changes that have been tracked by Entity framework so far in this case the addition of the new entity it translates that into whatever SQL statements needs to be executed into the database to insert the new record into the games table in this case all right and that's really all we have to do to transform our post method into a method that's going to actually work with our database and so let's see how this works uh in action so let's go ahead and open our terminal I'm going to do the net run right let's go into our games at HTTP file let me class this for a moment and we can go ahead and create our very first game now one thing I will have to change in this post that we have here is that as you as you know we are not sending the get gener as a string anymore we are sending the ID right so this has to be gener ID now now what id are we going to using here well we have to remember what id we're using uh when we create the gener so if we go back into Data gain store context remember that here is Will we declare statically which are the gers to be populated into the database so in this case well for Minecraft we're going to be using kids and family and this is ID number five right ID number five over here okay so let's close this and let's go back here and let's just put number five over here and with that we're ready to send the request so I'm going to just uh right click here I'll do send request and as you can see we are getting a validation error which makes sense because the price cannot be more than 100 so let me actually fix that very quickly for Minecraft it's going to be just $1 1999 let's once again right click send a request and the record has been created right we can see that Minecraft got created over there uh it got assigned ID number one by the database in this case ID number one and everything is looking as it should for a brand new Minecraft game okay and of course what we want to do now is verify that this actually exists in the database right now right which is should but let's let's confirm that so let's close this and I'm just going to stop my my server for now contrl C to stop the server and let's go back into our SQ Explorer let's right click on games and I'm going to say show table okay so if we put this on the left side we're going to see that uh yep indeed our brand new game Minecraft in this case has been created into our sqi database right so that since we working properly okay so so that's great uh but there's one thing that is not working as it should and perhaps we should notice that much better so let me close AQ light and uh yeah we didn't see that but let me go ahead and rerun our server and uh just for fun let's create micraft once again and let's see I'm going to hit send request so notice on the right side uh that something changed here right because the response that we were sending back to the client before did not include uh this this a composed gener object with an ID and a name if you remember before we were returning back here for the response just generate as a string right so by doing what we're doing here right now we have changed the contract of the response back to the client and we should not do that right we should respect the contract we were using so far we have indeed changed the contract for the inputs right because that makes sense right so now we have to the client has to send a general IDE and that's fine uh but we should not be changing the contract that of the response back to the CLI so what can we do to keep the contract as it was before right that we should understand what how to do that so let's go ahead and close this and let's now stop our server and let's go back into games end points so really what we should do here is instead of return if we returning if you remember we ret return in this game right here which is the actual entity we we should really never do we should not return internal entities back to the client we should always return our dto of data so what we're going to do is transform that game into a dto right so that that can be returned back to the client so we're going to go over here and we're just going to say okay so gain dto equals new and then we're just going to be filling in the properties so game that ID game that name game that in this case generate that name game that price and gain that release date now there's a warning here that says that hey this gener property might be null so is that okay I mean it's a possible null reference now we know from the fact that because we are doing over here up here remember that we are filling it it with the the right value for the gender right and the gender must exist because if it did didn't exist we are going to get some sort of foreign key related exception when we try to save the right so if we manage to get to this line over here it means that we indeed have a value for had a value for Jed right so it cannot ever really be null so we're because of that we're going to be using the null forgiving operator so this exclamation mark over there to say hey I am telling I'm going to tell you that gener is never going to be null at this point so you will be able to access name property just fine right and with that in place we can now return instead of the game we're going to be returning game game dto just like that okay and so with that change let's go ahead and rerun our server all right let's go back to games HTTP and let's see if we can create a different game let me just grab another game here from my other screen create a different game going to be Street Fighter 2 as you can see there we generate ID one and let's go ahead and uh send a request and as you can see on the right side uh yep so the game got created just fine it got a D3 which makes sense but more importantly if we scroll down we're going to notice that the gener now is back to what it was before it's just a simple straight that's what we're returning even when the input includes the generate ID as you can see there it's just the generate ID but the response is z so that's the way that we can keep that contract with the client even when our internal structure has changed right and this is why it is very important to give that separation between DTS and the data model uh because the DTs is a contract with the client with which you must keep at all times but the internal structure can change at any time and you want to have that flexibility all the time all right so let's close this and let's uh stop our server now if we go back into our code gam s points one thing that we going to notice is that ER I mean this is this method just got too big right there's too much going on here like we have to create our entity out of the new game create game dto and then we store it into the database and then we have to once again create a dto out of the game entity to return it back into the client so to simplify things a little bit here what we want to do is to have some sort of mapping logic right I mean the logic is there but we want to extract the mapping logic into some other class that can take care of this for us so we don't have to see so much code just in this method right so we need some refactoring here so there's a couple of things that you can do at this point I mean of course a way to deal with this is to be is to use a mapping Library like for instance automapper is a very popular choice to automatically map all of these fields from The Entity to the dto and to from the dto into the entity so that's that's one possible option and if that works for you that's totally fine uh but in this case since we only have very few properties what I'm going to do instead is a simple extension method right that is going to help us to do this in a very explicit way and it's very easy to understand so just keep in mind that you don't need to go all the way into a fully fledged Library just for this little mapping here I would only start thinking about such a library if the scenario is really complex right and if I have tons and tons and tons of properties I need to map and I have multiple entities and detos and all that maybe in that case but in this case is is very simple there's no need to introduce something like automapper a simple extension method should be good enough so let's go ahead and open up our Explorer here let's collapse this let's go into solution Explorer actually so so we can go ahead and create a brand new directory uh just under gain store. API let's right click new folder and let's name this mapping and in that mapping directory let's right click and add a new file it's going to be a class and let's name it game game mapping all right collapse this let's fix a name space control dot in the namespace Declaration to change Nam space to game store. api. mapping now since this class is meant for extension methods once again we make it a static class and we're going to create a couple of methods the first one is going to map uh create game dto instance into a game entity instance so let's create public static it's going to return game to entity okay so this is extending create game BTO new game all right and I guess we can just call this one game like that okay so what should we have here so if you go back to game end points we want to have something like this right this logic over here so I'm going to copy this into game mapping and paste that here now let's just scroll down a bit and what we're going to do is just say return new game okay and let's fix things a bit here so this is going to be just game that name now for the generate we cannot actually access the D context from here right so we're going to keep doing that back in G endpoint so let's remove this because we are not going to be sending the into this method we only care really about the dto okay and then for gener ID we have game that gener ID then we have game that price and then we have game. release date all right so that takes care of the first method and then we want to create a brand new one down here and this is other one is going to help us map a game entity back into a game dto so public static game dto to the so we're going to be extending game game entity right there like that now we what are we going to return here so going back to game's endpoints we're going to be returning what we do over here so let me copy this section down here okay and all we have to do really here is just say return new and yeah that's pretty much it that will return a brand new game dto so with this new extension methods ready we can now go back into games end points and take advantage of them right so let's go back first here where we are creating our new game instance so instead of that what we can do is say game game equals new game. to entity just like that but uh we still have to account for the for the generate entity that needs to be attached into the game so because of that we have to still do game. gener equals and that's going to be this line here line 59 we have to copy over there right there but the rest we can get rid of now so this can go away and uh one more thing so now for the game dto we can actually just get rid of this entire section let's get rid of that and here what we can say is at the very end and let me actually send these parameters to the next line so we can see better like this okay instead of sending game Det we're just going to say game. 2D that's all it is right now let's make sure that this is still working properly so let's open up our server our terminal and let's run our server over here okay the API is running and let's see if we can create a brand new game so let's go ahead and create a new game that I'm going to populate over here from my other screen so let me replace this with that okay it's going to be the Final Fantasy 14 game we generate ID 2 so let's right click let's send a request yep and as we can see on the right side it got created and it got assigned the proper generate here this role play right it has the ID so yep the mapping is working as expected all right let's close this perhaps let's also close this over there let's get back to gain sence with our post and point ready uh let's move on into the next Endo which in this case is going to be our get endo get by ID actually so let's see what we have to do to make this endpoint is start using our DB context so of course first thing to do is to receive the the context as a brand new parameter in the Lambda right so let's go ahead and add game store context it's going to be our DB context right there remember that this is injected via the DI and depend injection into our method at R time and now what we want to do is just change this line uh so that it uses the context and the game entity instead right so for that we're going to use switch this into just game and then here we're going to say instead of that DB context dot games. find and here would can pass in just that ID like that so that's how you can quickly find the entity inside the DB context now keep in mind that this find method is going to try to find the the game within the current set of games that are in memory right now already pulled in via the the DV context and if I cannot find them uh inside the D set the current D set in memory it will go ahead and find it in the database if need right so it's a very efficient method now one thing that we need to realize is that of course we don't want to just return the game right as we are doing right now like like we said we don't want to return the data model we want to return a dto but what dto we will return if we go ahead and return like we did in post if we return with two dto a game dto that's not going to work very well that is because let's just go ahead and I'm going to do contrl p here to take a look at game dto so game dto here we will be returning this and this is going to include the gener as a string however for a get by ID method we don't really want to return the generate as a string and that is because the client would likely want to have the generate ID to be able to use it in the UI right imagine a UI where the user is going to be selecting a generate from some sort of drw down list right and so that draw down list will have to match the generate ID that was returned by us but if we just keep returning the string that's going to be just too complicated right so the string is going to go work just fine if the client is going to have a summary of all the games right that's fine but if you want to see just one game what we really want to return back to the client is the general ID so because of of that what we're going to do is actually to create a brand new dto that is going to have that ID we're not going to modify this G dto but let's actually create a brand new one that we're going to name a game details CTO that's going to have the generate ID that can be used by our brand new G ID endpoint so let's go ahead and open up our Explorer contr shift e let's go into DTS and actually to keep things simpler let's go back into our file explor over here and let's uh let's just copy game d let's make a copy of this one and just right click on DTS spacee okay because it's going to be super similar so let's name this one game details dto just like that game details dto okay so game details dto let's rename that over here this is and like I said this is not going to have a string gener it's going to be an INT gener ID okay so that's game detail CTO now since we have we are renaming game detail CTO I mean we are creating G detail dto here it would make sense to also rename this game dto to give it a more proper name right so this is no longer going to be just game dto let's rename this one into game summary dto right to to more clearly reflect the fact that this is a summary of the game that includes a gener as a string and not an ID okay so this is going to be game summary dto now of course this is going to cause a little bit of trouble so let's go back into our game mapping and let's make a fure right so here where we have two dto this is going to do this is going to return actually a game summary dto and let's also rename the method itself so that this is going to say two game summary D okay that's what we should be returning from this method but also we want to here introduce a brand new mapping method to return a game detail CTO so let me just copy this method quickly let's scroll down and let's paste it down here let's let's change the type here into game details dto and this is going to say to game details dto right and here of course is going to be we're going to be returning game. generate ID all right and with that in place let's go back into our games end points over here and we may have to fix a few things before doing anything else so in this list this list is going to go away soon but for now just to avoid the compilation errors let's change this into game game suto then let's scroll down over here this is our post method map post so this should return now to game detail C right that's what would make most sense to the client right instead of returning that generate as a string it would make more more sense to the client to stick to just the ID right to the of the created and generate in the game d so two game details so yes we are breaking the contract here but let's say that we have come to an agreement with the client that this is going to be the final way that we're going to be returning that created a game from the poll okay so game details DET now let's keep scrolling down let's see what else we have here this should be game sumary dto okay so that fixes all of our errors there and then one more thing that you want to keep in mind here is that since we are going to be returning really only the details right game details dto and which if you remember let's go back to game details dto it does not include the generate as an actual object but just the gener ID because of that back here we no longer need to assign the gener over here with this line here there is no need because entity framew will take care of properly assign the generate into the game Into The Game's table he will assign the gener ID we don't need to populate that for the game entity we were really only doing that because we needed that later on for the mapping uh but really is not needed anymore and now let's go back to what we were actually trying to do here which is in map get get by ID what we want to do is instead of returning results the okay with the game over there let me send this to the next line we can see better we're going to return game do to game details D all right and so with that in place let's go ahead and run our API is actually running already so let's stop it clean the screen and then do run let's close this let's perhaps close this to DTS and let's go back to games. http I'm going to put this at the start and so we are going to do just to test our brand new method is to quer for one of the existing games so I'm going to use our second H request here to get a game by ID I'm going to right click and I'll hit send request and as expected things are working properly right so we are getting our 200 okay we are getting our Minecraft game here and notice that we are getting instead of the game U the game string or the name of the of the gener we are getting the ID of the gener here right in this case is generate ID five like I mentioned likely the client is going to use that ID five to match it to one of the gener that it is displaying on the screen right imagine some sort of drop down so he will use this to just select that that gener in that screen right for our user right so that's what we're going to get in that case and it's working as a awesome so that will take care of get by ID now let's go back into gains end points and I just stopped the server let's Now work on our put operation let's go down here into put now of course the first thing that we should do about put here is that we need to change our update game dto so that it can also use a generate ID and not a generate stream so let's go back into Explorer let's go into update game dto and we're going to be doing the same change that we did for create game d so instead of the string here we're going to say int generate ID like that and because of that now we have to go into our mapping to also Define some sort of a method to do the mapping between that update game dto and the entity so let me go ahead and actually copy the very first method let's just copy this and I'm going to just open a space here that copy and now we're going to be mapping not create game dto but update game dto right into the game instance now one thing that we want to also do with update it is not just to map the update game dto but we also need to account for the fact that this update game dto does not come with an ID right remember update game dto does not have any ID but we do want to create this game with an ID because the user has specified that he wants wants to replace a very specific entity with a specified ID so because of that what we can do is just to add one more parameter here that's going to be int ID and then we'll use that ID as the ID of our return game entity so let's assign it over here ID equals ID okay now how do we use these two entity method back in our endpoint so let's go back into games endpoints and here we're back in our put method okay so the first thing to do is to change this code here that is currently looking into our old games list and we need to make it so that we find the existing so to do that all we have to do is the following let's do bar existing game is going to be DB context and of course we have not injected that DB context into update so let's let's make sure that we do that first so game store context DB DB context right we have now injected that into our maput and we can take advantage of it right so DB context dot games. find and then it's going to receive that ID okay so now we we are finding the existing game and if it does not exist it will just return null right we'll get a null value over here so we can do now instead of this comparison is that we can say if a existing game is null then we going to again just return not found so that that stays okay uh but then we got into the interesting part right so how do we actually perform the updates well we have to do a couple of things first I mean of course we're not going to be doing this logic anymore here there what we want to do is to locate the existing entry inside our DB context and replace it with a brand new entity that we are creating here so to do that we're going to do the following we're going to say DB context that entry and entry is a method that you can use to locate the current entity inside that DB context right so for this one what we can do is just say existing game right and for inside that we we can say current values right so that pulls out the current values of that entity and then right there we're going to say set values okay and with for set values we can specify the new entity that's going to replace all of the values of the old entity so here we're going to bring in our updated updated game but the updated game is just a dto so what we want to do is just transform this into a two entity with the brand new extension method that we use two entity and passing in that ID okay and that is how with this just one line we can go ahead and replace the existing entity with a brand new entity that comes from the dto right and lastly last thing we want to do here is to always do D context do save changes to make sure that the changes are sent back to the database all right so that's really all we have to do for the put UT so make sure that this is working so let's go ahead and run our server okay I'm going to collapse this back toide HTTP so which game we are we going to actually update right so it's a bit hard to tell right now because we have not updated our get all logic right we cannot use this this still looking from the list so let's actually let's take a quick look uh pick into the database to see what we have so far so Esq Explorer right click on games show table okay so let's put this over here so we can see better okay so these are the games that we have so far so let's say we're going to update our stct Fighter game here which has ID number three safe Fighter 2 with ID number three so let's close this let's close that and we're going to go down here okay I think we have most of it but we don't have the the name so let me actually complete this very quickly with something that I have in my other screen over here and what we're really changing here is that Street Fighter 2 is not no longer going to be just a Street Fighter 2 it's going to be Street Fighter 2 turbo right turbo and the price has changed so game was number three so let's switch it to number three and let's go ahead and right click and execute our request so send request and we do have a problem here and that is because we forgot one small thing which is the gener right so gener should not be like that it should be generate ID and the ID of the generate 4 Street Fighter should should be one over there and let's right click and send a request there you go so we got the expected 204 no content meaning that this was a success so and to confirm of course we can go ahead and use Query for game number three by using our get by ID request over here right click Send request and as we can see indeed we are now using c52 turbo and and the price has changed so the update operation is working as expect awesome so now let's just close this and let's stop our server all right and let's go back into games end points because now it is time to change our and get all operation right so so we can actually start quitting for all of the available games so let's go all the way up here into our map get operation the first one that we have in our end is this one over here so how do we deal with this right so we no longer want to use the games list but uh first thing that we have to do as usual is receive our game store context instance here D context okay and then let me send this to the next line to see what we want to do so of course we don't want to return games what we want to do is a following we want to say d context. games and then from those games we want to transform each of those game instances into the corresponding game summary dtos right so to do that we're going to do is just a projection by using the select method from Link in C so do select right so for each game in this Games Collection we're going to say game dot to game summary dto just like that and well technically that's all we need to return our list of games as game suos back to decline but there are a couple of other things we want to do here the first thing that you want to realize is that uh to games Su if I just do F12 here I'm going to do F12 to go to the definition is that um we are going to need the generate property right here right to pull out the name of the gener and um the way it is right now so let's go back here the way this method is right now it is going to only pull out the gains but not the attached generat right so gener is going to come empty here so we have to do something to also include the attach generate property for every single game and that is if we just open up a brand new line here is this include method so include where we're going to say okay so for each game make sure that we bring in game.get right if you don't do this then this gener property is going to be empty it's going to be null when we pull out the games and we're not going to be able to do the proper mapping into two game summary dto to attach the general name into the dto right so that's very important in this case and the next thing we also want to do here is a bit of an optimization right because by default Entity framework is going to keep track of every single entity that we're pulling out of here is going to do change tracking for every entity and if you have many that's really wasted resources right we don't need to keep track of anything here because we're just going to return that back into the client right away just one operation so we're not going to be performing any updates into the return entities and because of that one of one very good optimization I should always do in these cases is just to say say as no tracking like this by doing that you're saying hey at the framework I don't need to do any tracking of the return entities just send them back into the client in this case as is right so that's going to improve the oper the performance of your operation over there okay and so yeah that's all we have to do for the get endpoint so let's test this quickly let's do theet run all right let's go back into G HTTP and now we can use our very first uh endpoint over there so let's right click Send request and as you can see on the right side now we are getting the actual gains from the database this case yeah we do have Minecraft duplicated here because of what we did initially well we're going to deal with that later but we do have out of our H I guess one two three four games declared into the database right now okay so that is working properly and notice that for each game we are returning the generate string and not the generate ID which is what what the client would expect to display a summary view of all of the available right and so one more thing to do here is to deal with the delete operation right so let's go ahead and stop our server let's go back into well let me close this and let me close that mapping let's go back to G end points and let's go now into our delete operation which is actually the simplest to implement so as with all the of the other endpoints first thing to do is to introduce our game store context via dependency injection DV context and then we have to change the way that we perform our removal of the entity so how will we do this so couple of ways to do it but the most efficient way is to do the following we're going to say d context. games. where and this where is going to be so that we can select which is going to be the one entity that needs to be removed so that end is going to be game where game. ID equals ID so that selects the game that we want to remove and let me actually send this to the next one and then when it finds that game what we want to ask it to do is to use to execute delete all right so this syntax here to perform the delete is is is known as batch delete and it is a very efficient operation because we don't have to first find the entity just to say hey framework keep track of the fact that I'm going to delete it and then go ahead and and save the deletion so this one line here one shot is going to go straight into the database find the entity and delete it right away so there's no need to do anything else here and then we just return no out and that's all it is okay so let's see if this actually works so let's go back again into the terminal let's run the server back to G HTTP and so if we remember if we right click at the very first request here we do have four games right so since we have this one duplicated so we have Minecraft two times here let's see if we can go ahead and and uh remove the second entry of micr ID number two right so let's close that let's go down here at the very end and yeah our delete operation is actually looking at game number two so let's ask it to remove game number two so let's right click let's do send request and it seems like was a success 204 no content means that it succeeded so if you go back into our list full list of games right click here send request and let's see what happened so we have ID number one but we no longer have ID number two as you can see there's no number two it is gone so the operation was a success awesome so let's just close this and then uh stop our server now one more thing to do here before moving to the next topic is that well we finally no longer need any in memory list of games right so finally we can go back here and we can get rid of this entire uh list of games so let's go ahead and select all of this and we can get rid of it so now it is gone okay so with that we have completely moved into a res API that is ready to interact with the database both for quering entities and also to create update or delete all of these entities so that is working properly but there is one more concept that we need to also learn and apply into a race API and that concept is the asynchronous pring mode so let's switch a slides so we can learn more about today a synchronous programming model and why it is so important to understand a synchronous programming let's go through a common scenario you might be familiar with which is making breakfast let's say you start by heating your pan for a few minutes and then when ready you fry some eggs there we would also like to have some bread for a breakfast so after your eggs are ready we bring up the toaster and toast our bread then then when the bread is ready we add some jam on peanut butter on it finally our breakfast would not be complete without some juice so let's pour in some orange juice in total it took us about 30 minutes to complete our breakfast but is that really how you would go about preparing your breakfast if it is a weekday when you are usually in a rush perhaps you would like to do something like this instead you start by hitting your pan and while that happens you will also start toasting your bread and while those two things happen perhaps you can also pour your orange juice eventually when the pan is ready you go back to it and fry some eggs and once the bread is toasted you go and put the jam or peanut butter on it doing things this way you can be done in much less time say 15 minutes and perhaps you can can spend the rest of the time enjoying your breakfast when comparing these two ways going about making your breakfast we say that the first approach is synchronous since you won't start a new task until the previous one is complete however the second approach is asynchronous since you don't wait for a task to be complete before starting your next task instead you start as many tasks as you can and eventually you turn your attention two tasks that are ready for you so you can continue with the next task in a similar way you can perform a synchronous programming in your hnet Cod applications when a client sends a request to the web server you want to start handing the request in your endpoint in an asynchronous way so that your cook the Krell web server is immediately free to start handing the next request so as your endpoint starts an asynchronous call perhaps to your DB context and the DB context in turn requests data asynchronously from the database the web server has also started serving the next request also asynchronously when the database eventually Returns the requested data the DB context will resume work and send the data back to the endpoint which in turns with Source work transform entities into dtos and sends the data back to the web server who in turn responds to the original client request after this the application continues starting order tasks asynchronously and resumes work whenever necessary as you can see the asynchronous programming model brings in multiple benefits your application gets improved performance since you avoid blocking colors and free them up to perform other tasks which also results in overall better responsiveness you are able to escale your application better because it can handle more requests and users simultaneously without getting bed down by waiting for Io operations to complete and also the use of task objects in combination with async and await keywords provide a simple and intuitive way of writing asynchronous code as opposed to having to deal with threads and callbacks directly now that you understand the asynchronous ramming model and its benefits let's see how to put it to work in our current res API taking advantage of the asynchronous Ring model in our net vers API is actually very straightforward so here we're back in a games endpoints right and so we're going to see how to introduce this autel model in each of our endpoints and let's start with our H map G endpoint here to retrieve all of our games so the first thing that we want to do is to modify a little bit the way that we talk to our database or to our DB context so that when we ask it to return the games it it does not just return the games but instead of that it is going to return a task that can be awaited until the operation actually completes that way a minut core does not have to block on the operation until it is done right so anything that goes out of your process like going into the database going to the file system going to the network all of those operations we want them to return just a task that can be waited and that can be resumed later on when the operation completes so in this case really all we have to do is just to add one more call at the end here to transform the output games into a a list in an asynchronous way so we're going to say to list async right and so that's going to now return as you can see it's going to return not just a list so notice this this returns okay so let's open up this this returns not just a list but it is a task of list right so because of that the wrong time can wait for that task and it's going to resume when the games actually come back from the database all right and you're going to notice this convention where you use the Asing suffix this suffix over here for every operation that is going to return not the actual object but just a a task that includes the result of the operation right so many libraries you're going to notice that they use this convention so prefer these asynchronous methods when you invoke these kind of apis right and you should also be using this same convention if you write your own asynchronous methods right so that works but the other thing that you also want to do is to use the async await combination of keywords for your own method now in this specific method here it may not be absolutely necessary because it's just a one liner here so arguably maybe you don't want you don't need to use that but just for convention just to keep things safe and simple to understand let's go ahead and add async and a weight here right so we're clearly signaling the compiler that it wants to execute this as an asynchronous operation and that it needs to await for the task here to complete before returning the data back into the client now we can follow this same convention across all of our methods to make sure that all of the operations work in an asynchronous way okay so let's go down into map get to get a Again by ID and just like with in the previous method we're going to now transform this into an async right so now it's an asynchronous operation and we need to await every single operation that goes outside of our process right in this case that's going to be this line here where we go ahead and find the game so we're going to say await wait all right and so but of course find it is not an aailable method it's just a simple find method that we need to now transform into find a sync just like that right so now just like in the previous method iset core is going to start a task to find the game and it's going to go back to it when the game is actually retrieved from the database let's move on into our post method now which once again is going to be an asynchronous operation and then what is going to be the actual operation that we need to wait for that's going to be our save changes so this is the only operation that's actually going to go outside of the process to save the the data back into the database so we're going to say wait and this is going to be save changes AC okay now let's keep going down into our put operation which we're also going to turn it into an async operation like this and here we have a couple of asynchronous operations the first one is going to be the one here to find the game this one in line 53 so this we should await await and then find a sync right so now we can find it in a synchronous way and then we go all the way down into save changes and again we want to do await save changes async finally let's go down into our delete operation which again we're going to make it a sync and then the the operation that we want to wait here is to is to is the execute delete over here so remember that this goes straight into the database to perform the deletion so we're going to say await and then execute delete a sync all right and well that really takes care of all of our API endpoints now everything going on in this endpoints H class is really asynchronous but there's one more location where we should also take advantage of the synchronous grabing model and that is the location where we perform the migration when we start application so where is that happening let's go back to Explorer let's collapse this and let's go into go up data extensions under our data directory data extensions so remember that this is the place where we eventually go ahead and just execute any pending migrations when the application starts so this should also work in an asynchronous way right because it has to go out and talk to the database and that could take time so what we're going to do is change this operation in a few ways the first thing is that since we're going to be returning uh no longer just a standard return but a task right we have to be very clear about this so it cannot longer be void it has to be a task so that whoever calls this operation can actually await on that task now we also need to follow the async and a weight convention right because that simplifies the way that we can deal with this task and then instead of calling migrate we want to call migrate async okay and now our method is really an asynchronous me but remember that I mentioned that anytime you deal with asynchronous operation you should name your methods with an async suix so that's a convention across the entire net and C ecosystem so just like myig async uses the async suffix over there you want to also modify your myig gr DB method here so that it's name my grade DB a sync right just like a as a convention and of course since we're doing this we have to now go back into program CS over here and in line 133 we have to make it so that we take advantage of the brand new name made so my great DB async now no this is warning here so this warning is alerting US of the fact that this method is asynchronous right because it Returns the task but we are not waiting on it right so if it is a task we have to make sure that we actually await on it before moving on to the next next step because of that all we have to do is just say await over there and that is going to properly wait for the task to complete before moving on to the next thing all right and so yeah that's pretty much all we have to do at this point to take advantage of the in programming model and what I like to do uh to make sure that everything is working properly including this this last change is to well let's go ahead and delete the database and let's see if when we run the application it can actually recreate a database and then we're going to start testing our a points once again to make sure that everything is working properly with the singles grabing mode so let's go ahead and open up our Explorer let's make sure also that yeah the server is not running right now so let's right click and delete our game store database so delete okay the database is gone so it has to be recreated when we restart the application so let's go ahead and open our terminal okay let's collapse this do and run let see what happens all right apparently everything went properly the migrations were applied as you can see here migration got applied we should be able to see the database back here so yeah as you can see the database is back so that work just fine and then let's just go ahead and test perhaps one um post operation here to verify that things are working properly so I'm going to right click here send request yep the post was a success as you can see the game got created and we should be able to also query for games up here so right click here send request yep we can query for games so things seem to be working just just fine and now we're taking advantage of theing Prim model which makes things much more efficient for our net R API right so let's go ahead and close this and let's stop our server all right and get back to games endpoints that's CS at this point our games endpoints are complete and what i' like to do now is to show you how these endpoints can be integrated into a modern web client but before we can do that there's still one missing piece and that piece is our generous Endo because we have the ability to fully interact with games right now but we don't have that ability with the genders and it's not like we need an entire API and a set of endpoints for generes but we at least need the ability to be able to query those generes because we have some UI elements in the client that are going to need to query for those gener so let's go ahead and apply everything we learned so far about net apis to see how quickly we can come up with a brand new endpoint to be able to query for those Jers so let's go ahead and close all of these so let's close all these tabs let's go back to Explorer and the first thing that we're going to need is a brand new dto which is going to be the dto that represents the generous so let's head back into solution Explorer and let's go ahead and right click on DTS new file remember that this is a record type and let's name this one generate dto all right let's collapse this let's go ahead and fix our namespace install that api. dtos so pully record class generate dto let's use the simpler syntax here to specify an ID and a name all right so now we have the dto let's go ahead and Define a proper mapping for Transforming Our gener entity into gener dtos so let's go into the mapping directory and let's actually spin up a brand new mapping class because this is going to be for mapping generous right so let's not mix that with games so let's right click on mapping add new file going to be a class and let's name it y mapping okay let's collapse this let's fix a name space it's going to be G start. api. mapping and then this is going to be a static class because it is for extension methods let's define just one method public static gener dto to dto and then we're going to be extending the gener class which is already defined in our data model so gener and what we're going to do here is just to return a new Genero with generate. ID and gener do name all right so the mapping is ready and then the next step is to Well define the actual end points to be able to query for these J right so let's go back into solution Explorer and in under our endpoint directory let's go ahead and and create a brand new endpoints class this time for the generous so let's right click on it end points new file going to be a class and let's name it generous endpoints all right so here let's go ahead and also fix an name space gam store. api. end points it's going to be a static class and let's follow the same idea as the previous endpoints class so it's going to be a public static and we're going to be returning a route group Builder right because we're going to be using route groups here let's let's name it map generes and points and then let's extend our web application class app right so remember that we can first create this map group this way so bar group equals app. map group so our group is going to go into generous right generous and then uh let's go ahead and Define just one one endpoint so group. maret okay so this is going to be go just under generate so we'll just put that forward slash over there and then for the Handler we're going to be using a syn a synchronous operation to query for those generat so it's going to be a sync and then for the parameter for the lamb we're going to be receiving our game store context once again install context DB context and then we have to specify something something to do with this with this Handler right right so let's go to the next line let's close this and here what we're going to do is just say await okay so how do we retrieve all those gener well we use a DB context so DB context dot generous right now if you remember here's where we have to project the generes that are in the data model into corresponding dto and we can do that easily by just going let's go to the next line we're going to say do select okay so for each gener we're going to do generate. Toto all right and then remember we also said that um for this kind of operation that does not need any tracking for an Entity framework then we just want to send back the genders directly to the client we're going to say that as no tracking and lastly we want to make sure that this returns an async I mean returns a task as part of an Asing operation so we're going to do two list async okay and let's actually send this to the next line like that all right so that defines our end point and last thing to do here is just to return our group awesome so yeah so the endpoint is ready and last thing to do here is to actually take advantage of this method in a PR CS file so this time we're going to just close solution Explorer let's go back to file explorer and I'm going to open up my pram CS file over here and just under map games end points I can insert a brand new line and let's just say app. map generous endpoints like that all right and so yeah we're we're ready to query for those generous so let's see this in action let's do net run and what we're going to need here is perhaps a new HTTP file so that we can add our new request for J right so let me collapse this because we do have this gamat http but since this is different so let's actually add a new one for gener let's just right click add the root in the file explorer new file let's name this one generous. HTTP there and all we're going to do is just say here get and then well we need the actual endpoint so remember that we have that here in a few places so let me copy this from our other file there and then the pad is going to be under generate right all right so that's it so I'm going to collapse this and let's just right click on this and let's say send request so as you can see on the right side this was a success 200 okay and we can see down here that we are properly returning all of our game genders so just like that we have stand up a brand new endpoint that our client can use to get the full list of all of these genders awesome so let's go ahead and close this and let's stop our server and and with that we're ready to go to the last part of our tutorial which is where we're going to integrate this netr API with an actual client application now this is totally optional because we have already done all of the backend work here and that's what we wanted to aieve but I also like to always see how this actually serves the purpose of some client because there's really no point of having an API if there's not going to be an actual client for this that that's a whole idea right so I have prepared a a small client so we don't have to code this the client is ready so I'm going to open up that client in this other vs code instance over here I named it gam store. front end this is a very simple blur application with serers side rendering so nothing fancy really and I'm not going to go over the code of this H front end here if you want to know more about this front end and how exactly I built it I have another video where you can see the process from scratch how do I I created this little front end here is very simple really uh but um really all we have to do here at this point is configure this frontend to be able to talk to our API and I have prepared a section in abs. Json here where I all all I have to do is just to enter the URL of our backet right so what is that URL let's go back into our other vscode instance and remember that our our URL is right here so it's Local Host 5274 I'm going to copy that and let's head back into our front end and I'm going to paste it over here okay so now our front is ready to start talking to our back end so let's see this in action so let's go back into our back end and let's just do run so the back end starts it's ready let's go into our front end now let's do something similar right since this is Blazer all you have to do is just don't it run all right so it is up and running and I'm going to go ahead and click and this is the this is the URL of our front end right so not the the back end but the front end so I'm going to just uh control click on that one so this opens my browser and as you can see we can already list the one game that we have right now in our back end okay so not much going on here all is this is is render rendering a simple table with the list of games and for each game you can see that we have uh butons for editing the game deleting the game and there's also a Buton over here for creating a Rand so let's actually go ahead and click on new game so to see if we can spin up a brand new game over there so notice that we have the drum down list over here and this is the list that I was mentioning that is going to go ahead and pull the list of generes for our game right so this is pulling from that list that we just created that back that res API for generous that's that's is the Lisas using it right so let's go ahead and see if we can create a brand new game so let's go for let's see El ring awesome game so it's going to be role playing the price is going to be $49.99 and then let's go ahead and enter some date for this is going to be February 25 2022 right and then let's go ahead and click on the save button and as you can see it went ahead and stored our game right here okay and we can confirm that this actually talk to our API because we can go back to vs code of course and we can take a quick look at the database over here vs SQ we can right click on games show table and we can see that the brand new game got created over here here right so this is really talking to back to our receip okay and so let's see how what we can do about an update operation perhaps right and so let's see let's go ahead and update this Final Fantasy 14 game over here so I'll click on edit let's make it so that the game is a bit pricier so let's say it's going to be $69.99 let's go ahead and save the game save and as you can see it did save it properly without any any problems all right awesome and then uh yeah before we try the delete let's actually come up with something something that we can delete and we can keep the other games in there so let's just save this test game here and now I'm going to go ahead and click on the delete button over here to see if we can delete this game and the game is gone so yeah there you go so you have a res API that can fully integrate with a modern client like this one and I hope you enjoyed creating this this res API with me like I said if you want to take a look at how I created this client there's another video for that but at this point thanks for watching and I'll see you in the next video
Info
Channel: Julio Casal
Views: 71,660
Rating: undefined out of 5
Keywords:
Id: AhAxLiGC7Pc
Channel Id: undefined
Length: 223min 18sec (13398 seconds)
Published: Thu Feb 22 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.