⭐ If you would like to buy me a coffee, well thank you very much that is mega kind! : https://www.buymeacoffee.com/honeyvig Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies

Friday, November 7, 2025

ASP.NET Core Full Course For Beginners

welcome to this beginner level course where you will learn how to build a complete web application step by step

0:07

using ASP.NET core and the C# language  and I spent the last

0:12

decade building all sorts of cloud-based applications that handle millions of requests every month by the end of this

0:19

course you will have master all the skills necessary to start your journey into C backend development even if you

0:25

have never created a web application before so let's get started by taking a quick look at the application that you

0:31

will build across this curse imagine that your team has been asked to build a

0:37

game catalog section of your company's video game store the frontend developers

0:42

already took care of building the web UI for this game catalog where administrators can manage the

0:48

information about all the games offered by the store now you as the backend

0:53

developer need to figure out a way to stand up the back end that will provide all the game data required by the front

0:59

end the game data lives in a relational database with tables for games and game

1:06

generous and to let the front end access all these data you will create a new res

1:12

API that will provide all the standard operations to create list update and

1:19

delete games in this course you will create this backend from scratch using

1:25

the latest Innovations in Asad net core and C if you're interested on the front

1:30

endend portion of this system please check out my blazer tutorial link to

1:36

this video where I cover how to build that part in detail now creating an hn

1:41

net cord backend involves understanding multiple Concepts techniques and patterns that I'll cover in detail in

1:48

this course you will start by learning how to create run and debok your first

1:54

spnc application from scratch then we go over the Core Concepts behind

2:00

rest apis and how to quickly implement the traditional grow endpoints in an hnet core API as you implement your res

2:08

API you will also explore the use of data transfer objects or dto to define

2:14

the contract between your API and the front end then you'll see how to use

2:19

extension methods and Route groups to properly organize your API endpoints you

2:25

will also spend some time trying out invalid inputs to learn how to ensure they are properly handled by your API

2:33

next you will introduce real database support via the popular Entity framework core or framework which is included with

2:41

the net platform this will also be a good time to explore the hnet core configuration system which will help you

2:48

avoid hardcoding important configuration details in your C code next you will

2:53

explore in detail the dependency injection design pattern and how service lifetimes work in ESPN code

3:00

applications you will also learn here how to properly map your entities to DTS

3:06

to ensure you maintain the data contract with your front end while keeping a flexible data model you will complete

3:13

your R API implementation by introducing the asynchronous programming model which

3:18

will ensure your application use the web server resources in the most efficient way and to close I'll show you how your

3:26

rest API can nicely integrate with the front end to light up a modern user

3:31

experience in order to take this course you should have some basic knowledge of C Java or a similar object oriented

3:39

language you should also know the essentials of web development and it would also help if you have some

3:45

experience with relational databases however this is a beginner level course so you don't have to be an

3:52

expert on any of these topics since we write every line of code from scratch and everything we do is explained in

3:59

detail in terms of the software prusy for this course you will need to download and

4:04

install the following the net software development kit or SDK which includes

4:10

everything needed to build and Run net applications and visual studio code a

4:16

lightweight but powerful seource code editor that you will use to write build and debug your code please go ahead and

4:24

install these tools Now using the URLs on screen if you don't already have them you will also need a few vs code

4:30

extensions but we'll get back to those later in the course with the net SD and

4:35

vs code installed let's see how to properly configure your development environment let's see how to configure

4:42

Visual Studio code to work with SPN net core applications now Visual Studio code is a

4:47

very powerful code editor but we're going to need a few additional extensions to improve our C coding

4:53

experience and also to be able to interact with our res API so the first thing that we're going to do is just

4:59

head in into the extensions view right here so let's go into the extensions View and then let's go ahead and look

5:05

for uh the C dev kit so you want to just type c here and the first kit is going

5:11

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

5:17

this one here and the dev kit is really the an extension provided by Microsoft

5:22

that is going to overall improve the experience of coding C and working with

5:27

C projects in Vis Studio code now this extension does not install just

5:32

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

5:38

install uh to start with the c extension this one over here which adds the base

5:43

language support for C inside V code so that it can recognize all of the C

5:48

syntax it of course it also installs the def git itself which is the extension that provides additional um improvements

5:56

to V code things like for instance a solution Explorer so you can more easily manage your C projects and um create C

6:03

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

6:10

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

6:16

little bit of AI assisted development as you're typing your C code and lastly it

6:22

also installs theet install tool this extension over here uh which what it does is is really a tool that provides

6:28

the net run time or the net SDK to other extensions if they need to and so that

6:34

is what we need in terms of C development now the next extension that I recommend you install is one called

6:40

rest client now this extension this is an open source free extension that uh

6:45

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

6:53

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

7:00

extension that you should install is an extension for SQ light okay so it's going to be the very first one over here

7:07

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

7:13

the SQ light database that we're going to be using across the tutorial all right so yeah so those are the

7:18

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

7:24

that we should do is to make sure that well that net has been properly installed in the machine right just like

7:30

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

7:36

bar terminal new terminal over here and by the way a quick chart code for this

7:42

at least on Windows is either control TI right you type control TI is going to toggle that terminal for you or you can

7:48

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

7:55

to do is just verify that net is in the box so just type net D Das version and

8:01

that's going to print out the version of the net s that you have in your box you can also

8:06

do ninfo and that's going to give you even way more information about everything

8:12

that uh is related to the net SDK installation that you have in your box and with that done let's see how to

8:19

create our web project now Vis to code and by having the net SDK installed

8:25

there are a couple of ways to create your net projects the first way is directly from the terminal so here in

8:32

the terminal let me go ahead and just clean this very quickly CLS and one way that you can do this is using directly

8:38

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

8:45

you to pick from a series of templates to create your projects now what what templates we have available here all you

8:51

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

8:57

you the full list of all the POS ful types of application that you can create with your local SDK installation all

9:04

right so for instance if you want to create a web project you could choose this one template here for instance

9:10

hbnet C empty web right that will go ahead and create a fairly empty a that that web project however since we

9:18

installed the C dev kit um there is another way that you can also do this so

9:23

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

9:28

your command plet by going into your menu over here so just go into your menu into view Command plet right there which

9:38

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

9:44

there are many many many commands available here uh across the many things that Vis Studio code can do now in this

9:50

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

9:58

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

10:05

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

10:12

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

10:19

now we could go ahead and choose the aset core web API project template over here which is what you would use if

10:25

you're are more experienced with web API development but if you're new what I recommend is that you start with the xet

10:31

core empty template over here because that will go ahead and create only the minimal set of files and configurations

10:37

that are needed to get started and then you can learn slowly how the different additional pieces are going to fit

10:43

together right like Lego pieces you're going to learn how to stack each of these pieces and what what exactly is

10:48

each of these pieces doing right as opposed to start with a bunch of files and configurations that you may not

10:53

understand at the start okay so we're going to go ahead and create a brand new application with esinet core empty

11:00

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

11:07

right so I'm going to be using my D projects directory here you can use any directory in your machine but what we

11:13

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

11:19

doing is creating an API for a game store and specifically the API to

11:24

retrieve or to manage the list of games the video games in our game cap so because of that we're going to be

11:29

creating a brand new project over here brand new folder sorry which is going to be named game

11:36

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

11:43

folder down here select folder and that is going to make it so that vs code

11:48

opens that directory turning it into the workspace where we're going to be

11:53

creating all of our projects now from here the last thing that we have to choose is the actual name for the

11:59

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

12:06

store. API let's hit enter and now vs code opens like I mentioned our

12:13

directory our game store directory and as you can see on the left side we now have our brand new game store project

12:19

created over there alongside with a solution which is the one that we can use to group the different projects that

12:26

build our application right now one thing that you should notice is that there's not one but two ways to explore

12:33

the files that got created for your project now the first way is of course the one that we are seeing right here

12:39

right this is known as the file explorer and this is showing all of the files the physical files that compose our our

12:45

current project right uh but there's also this other Explorer but you can see down here is known as a solution

12:51

Explorer and this is more of um a virtual View and let me expand this a bit this a virtual view of the files

12:57

that the files that compose your application where we're not going to see every single file for instance you don't see

13:02

either the bin or obj directories over here they are not going to be seen here because this view is more like to help

13:07

you uh manage the dependencies across different projects and also to help you create a files for C files for your

13:16

solution we're going to see how this solution is going to be very handy in several situations uh but for the most

13:22

part we're going to be working mostly with the file explorer which is going to be a good enough for most tasks now

13:28

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

13:34

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

13:39

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

13:46

the only C file that is available in your project and this few lines of code

13:52

that you can see here are the very first lines that execute when you run your application so this is the code that

13:57

pretty much boot St your application and the whole purpose of this lines here is to really create an instance of this

14:03

web application of here so app here is really of type web application and web application is what we know as a host

14:10

the host of your of your application now what is the purpose of this host well the purpose is really to represent or to

14:16

introduce an HTTP server implementation for your app so that it can start listening for HTTP request it also

14:23

stands up a bunch of mware components a login Services dependency injection services configuration Services a bunch

14:30

of services we're going be going to be talking about across this tutorial and that you can configure over here if we

14:36

expand this between between these two lines you could go ahead and always just type Builder Dot and this is going to

14:42

give you the chance to go ahead and configure a series of services depending on your needs right uh by default as you

14:48

can see there's nothing in there but we're going to be working a lot with this Builder object to introduce

14:53

Services as we go across this tutorial now when you actually go ahead and invoke built over here this is going to

15:00

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

15:05

set up castrell as your inprocess web server that comes in with with esinet

15:10

core it also lows configurations from a few other F we're going to be talking about and also configurations for

15:16

environment variables command line arguments and many other configuration service sources it is also going to

15:23

allow us to send the login output into the console that we can see in the terminal all right and so after we have

15:30

this instance of Apt ready then we go into what we know as as as the configuration of the request pipeline so

15:37

all of these lines and let me just s here between line three and seven here is what we know as the configuration of

15:43

our request pipeline so this sets up what is going to happen when requests come in how should we handle those

15:49

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

15:54

says well if a request comes for the get verb this get verb into the root of my

16:00

application I'm going to reply with this Lambda expression that you can see here this is known as a Handler it just

16:05

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

16:12

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

16:19

modify what happens when this request come in right that that's done as a request Pipeline and again we're going

16:24

to see how to take advantage of this app object across this tutorial okay so yeah

16:30

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

16:35

important file is is known as the project file this gam store. api. CS Pro

16:40

what is this file for now this this is known as a project file and this one defines a few things like for instance

16:45

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.

16:52

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

16:58

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

17:05

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

17:11

all of the apis that are available in version 8 of the net SD right so if you

17:17

have a lower version it means that you have access to likely less apis you have a higher version you have access to

17:23

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

17:28

why it defaults to net net data Z right and then there are also configurations

17:33

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

17:39

spr as we go through the tutorial is that this is where we're going to be declaring all of the dependencies or

17:45

other libraries that that we may want to use to take advantage of their functionalities without having to write

17:51

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

17:57

let's take a look at are ABS Json now we have Absa Json and Absa development Json

18:02

so these are the files that are commonly used for configurations right so this is where you would put everything that

18:08

should not be hardcoded into into your code base but more represents a set of configurations that could change across

18:15

environments right so for instance right now we already have some configurations for logging right uh but we also have

18:22

this ABS since that development Json that we could use if we wanted to so that it only works in the development

18:27

environment so in your box but these settings will not be us it as you move into production for production you could

18:32

either use ABS in Json or you could introduce other set of configurations from other sources and we're going to be

18:38

talking about those configurations later in the tutorial right now another file that we have here is under properties

18:44

there's this launch series that Json file let me collapse this for a moment now the main purpose of this launch S

18:50

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

18:56

profile and down here we have have an https profile now these profiles provide you with some configurations only for

19:03

development so this is just for local development um that kind of impact the way that your application is going to

19:09

run in your box for instance this setting here states that the browser should open anytime you start debugging

19:14

your application and this one here is the URL that's going to be assigned for your application when you started this

19:22

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

19:27

something like environment variables as you can see here this environment variable H netod environment is a

19:33

well-known environment variable that tells the netor time or ESP cor on time that we are working in a development

19:39

environment not in a production environment right and so nothing in this file is going to available in production

19:44

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

19:50

development now just like you have HTTP if you wanted to run with https you can take advantage of the https profile

19:56

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

20:04

what else we have here well we have our bin and obj directories which is really where our temporary files I mean in obj

20:11

is where we're going to have our intermediate files as we go into the compilation process and later in bin is

20:17

where we're going to have the final DLS or assemblies for our application okay

20:23

so that's it really for for the files that we have in the application let me collapse this close this and close them

20:29

now how do we actually build this project how do we end up I mean going from the code into the the binaries so

20:35

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

20:41

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

20:47

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

20:53

store. API right click click on build and that's going to go ahead and keep kick off the build process based on the

21:00

solution that you have currently right and as you can see right here we have

21:05

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

21:13

into our file explorer into bin let me expand this a bit uh there's bin debug

21:19

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

21:25

store. api. so that represents the actual assembly or the compiled version of our application okay and so yeah and

21:33

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

21:40

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

21:46

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

21:52

really is just type net so net C and then build uh that's going to go ahead

21:59

and and build whatever solution or project you are in so since right right now I am at the rout at game store it

22:05

builds the solution game store sln that includes the project that I'm working on right now okay so that produces the the

22:11

D and one last way to do it if you wanted to do is to by by using control

22:16

shift V control shift V which is going to tie into the native BS code integration into what we know as build

22:23

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

22:28

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

22:34

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

22:40

run it it's actually very straightforward easiest way to do it is by just hitting the F5 key so if you

22:46

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

22:52

to be the debugger for your application right because this is going to actually go into a debug session not just run the

22:58

application but into a debx session now of course we're working with a c application right so you want to pick C

23:04

here right and now you have to pick what is going to be your your configuration that you want to work with like I

23:11

mentioned before uh in L Json we have two profiles one for HTTP and one for https and there is also the concept of

23:17

the default configuration which is going to be really the HTTP configuration so let's just go ahead and click on the default

23:23

configuration and now BS code is going to go ahead and build the project and then it's going to kick off the debugger

23:29

with a with a debugger attached into the application and as you can see it even went ahead and open my browser and let

23:35

me expand this for a moment it open my browser and it went into executing a get

23:42

request into the API right and as you remember if you go back into vs code what happens if somebody executes a get

23:48

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

23:54

what we're seeing in the browser right now you're returning hello word notice that we are right now at the host and

24:01

Port that was specified in lunch settings that Jason right so Local Host 52 74 would match what we have set in

24:09

properties launch sa. Json is going to be up here Local Host 52 oops 5274 right

24:17

so that's what got launched over there but then like I mentioned this is not just running application it's actually

24:23

inside a debu session and how can we tell that we are actually in a Deb session though let let me show you that

24:29

so let me go back into vs code and I'm going to temporarily just stop the debugging session for a moment so you

24:34

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

24:40

place a break point in my Pam CS over here perhaps over there which is where

24:46

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

24:56

code is going to build the project and attaches a debugger into the application and as you can see this time we actually

25:01

a stop over here in the breakpoint line five H and from here we can go ahead if

25:06

you wanted to and start evaluating the different objects that are live now in the application right so we could go

25:12

ahead and hover over app for instance and that's going to give you give us the values of the different objects that are

25:17

available right now from from AIT core right the web application object and not

25:23

just that we could see variables I mean the Builder the app on the left side we could add what

25:28

we could check out the call stack also if you wanted to but indeed we are in a

25:33

debugging session and to continue all you have to do is just click over there over here click on that play Buton and

25:40

that's going to continue the execution now this opens up the browser once again browsing into the root of the API but we

25:46

have hit the breakpoint once again and that is because now we are inside the Lambda that executes when the actual

25:53

request lands right the first time it executed because we were booting or St star up the application and now we

25:59

actually hit the get endpoint and we are invoking the this hello word L okay so

26:05

just click on play once again and back in the browser you're going to see that it presents the hello word once again

26:12

okay so that's how you can I mean easily start debugging your application now

26:18

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

26:24

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

26:29

debugging session what you can do is either go back into Explorer right you can go into solution Explorer and you

26:36

can right click in your project over here you can go ahead and say debug and then you could do a start without

26:42

debugging right start without debugging so this is going to start your application without any debugging support notice that it was way faster

26:48

still opens the browser but it was way faster right or another thing that you can do right let me stop this once again

26:55

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

27:02

this for a moment and let me expand my terminal going to Cod these three dots and into terminal over here I'll kill

27:09

this terminal back into this simpler one okay and I'm going to switch into gam store. API which is the location of the

27:17

actual API that that we have created and I'll just type net run by doing that

27:22

once again I'm running the application right but there's no debugger attached and we are going to see in nice colors

27:28

the the logs that are going to pop up out of the application and we can clearly see where is that we're hosting

27:33

the application Local Host 5274 so by being here I can again once again go back to the browser just

27:39

refresh this and again it's going to send back hello word right and so now

27:45

that we understand how to create a project and how to build and run it uh let's now switch into slide to

27:51

understand much better what exactly is a res API in this section you will learn

27:57

what are a res API is and how it relates to Modern client applications to understand what a res

28:04

API is start by thinking about all these apps you have in your phone like your

28:09

weather app LinkedIn or Spotify these apps use a ton of data

28:16

like the latest weather information the latest post in your LinkedIn feed or the hundreds of songs in your favorite

28:22

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

28:29

data to store in your device and you want fresh data all the time anyways so

28:34

the data has to come from someware and that someware is going to be some sort of server computer that usually leaves

28:40

someware in the internet Cloud but how can these apps talk to that server in

28:46

the cloud to retrieve that data well by using an API API stands for application

28:54

programming interface and it's how a service defines the functions it provides to

29:01

clients so for instance going back to the Spotify example the Spotify cloud

29:06

service could Define an API with two functions a get recent songs function

29:12

that receives the username as a parameter and that Returns the 10 most recent songs for specified user and

29:19

there could also be a play song function that receives the song name as a parameter and that Returns the stream

29:26

for that song so that a client can play it like this there could be dozens or

29:32

hundreds of other functions offered by the service that clients can use to interact with it so an API helps clients

29:40

communicate what they want to the service so it can understand and fulfill the request rest stands for

29:48

representational State transfer and it defines a set of guiding principles that

29:55

impose conditions on how an API should should work we won't dive into each of these principles in this tutorial but

30:02

the important thing to know is that thanks to them you can build apis that are scalable flexible and independent of

30:09

the technology being used on the client and the server so going back to the original question a rest or restful API

30:18

is one that conforms to the rest architectural style now the main reason

30:23

why we want to stand up a rest API is so that our clients can interact with the

30:28

data that it manages but how do they actually reach that data well for this it's good to

30:35

First understand the concept of a resource in a res API in a res API a

30:41

resource is any object document or think that the API can receive from or send to

30:48

clients for instance in our game store application the main resource is going to be our games that's what clients want

30:55

to query and modify but in other applications like the Spotify example one of the resources

31:03

could be the songs and in in the LinkedIn example one resource could be the users and another

31:10

one the LinkedIn posts these resources will be hosted on some domain which

31:17

could be a public domain an internet location or it could be just your de

31:22

boox and they can be accessed either via the HTTP protocol or the https protocol

31:29

which is a must in public environment so when you combine all these you get what we know as a uniform

31:36

resource identifier or URI and that is what your clients will use to identify

31:42

and reach resources of a res API there could be more parts to this URI but

31:48

these are the essential elements now how do you actually interact with the res API well just like

31:55

with traditional web pages when clients want to request something from the servers they will send an HTTP request

32:02

using the resource URI to the server and then the server will send back a

32:07

response however in rest apis these requests and responses will look a bit

32:13

different depending on the specific HTTP method used to call it the most common

32:18

methods are post which creates new resources get which retrieves the

32:25

representation or state of the res resource put which updates an existing

32:30

resource and delete which deletes a resource so these methods allow you to

32:37

create read update and delete resources and therefore they are also commonly

32:43

known as Crow operations there are other methods too but for the purposes of this tutorial

32:50

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

32:57

understand better how they work to request all games a client will send a get request to the game's endpoint and

33:05

the server will respond with something like this the first part of this response is the status which is 200 okay

33:14

in this case this means that the operation was a success there are many

33:19

other HTTP status codes that AR rest API will send back depending on the result of the operation many of them for

33:25

failure scenarios the next part is the body which contains the list of games in this case notice

33:33

that this body is not HTML but instead the format of the response is known as

33:38

Json which stands for JavaScript object notation this is the de facto format for

33:45

sending and receiving data in res apis because of how easy it is to read and write and is supported by all major

33:52

programming languages If instead of getting all games you wanted to to get a specific

33:57

game you would again send a a get request but this time you would append

34:04

the resource identifier at the end number one in this case the server will

34:10

respond with the state of the game with that identifier assuming it's able to

34:15

find the game to create a game the client can send post requests once again using the games

34:23

resource URI but this time it needs to specify the desired resource state in

34:28

the body of the request which in this example only includes the name of the game but could include many other

34:35

properties of course the server will usually reply with a 2011 created status

34:41

code and if the resource identified was not specified as part of the request body the response will usually included

34:49

to obtain an existing game the client sends a putot request with the same resource URI as they one to get a game

34:56

but this time it includes the resource State just like in the post scenario the

35:02

server will completely replace the state of the game associated with the specified identifier with a new state and will

35:09

typically respond only with a two or four no content status code finally to

35:15

delete an existing game the client sends a delete request to the URI that identifies the game to delete and after

35:22

deleting the resource the server will usually respond with a 204 no content St status code so in summary your complete

35:30

games res API would look like this and should offer all the support that your

35:36

clients expect from a modern backend let's now jump back into the code to see

35:41

how to implement this res API in a net core before we start implementing our

35:47

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

35:53

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

35:58

is find another way by using directly Visual Studio code to talk to the API and let me show you how that works so

36:05

back in BS code in our file explorer let's go ahead and just right click on

36:11

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

36:19

the file doesn't really matter what matters is extension and this file is recognized by the extension that we sted

36:25

before this one called rest CL that extension allows us to write a

36:31

statements directly in this file that very quickly allow us to interact with the API so for instance remember that we

36:38

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

36:43

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

36:50

Port of our running API so to figure that out remember you can you can always always go into launch sajason look at

36:57

your HTTP profile this profile over here HTTP and here is your application URL so

37:03

I'm going to copy this close that I'll just paste it over there and now we are

37:09

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

37:15

to open my terminal here I'll switch into gam store. API and I'll just do net

37:22

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

37:27

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

37:32

I have declared this line line one I just right click and I'll use this this option here that says send request send

37:38

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

37:44

away including the hello world that we were already expecting that we were seeing before in the browser now we're

37:51

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

37:58

response and so you can also go here I mean there is this send request link

38:04

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

38:10

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

38:16

also do to do Control Alt R in Windows at least Control Alt R is going to go

38:22

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

38:29

that we still have is that anytime we start a debugging session the browser is is still going to open right so if I

38:35

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

38:41

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

38:47

and the breakpoint is been hit I'm going to remove this breakpoint and then the browser opens again right so this is not

38:53

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

39:00

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

39:06

just go and I'll do control shift e to open my Explorer View and I'll go into

39:12

my launch settings at Json file right and so in this file all you have to do is just switch launch browser from

39:19

through to false and I'll do that both for my HTTP and my https profiles right

39:25

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

39:32

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

39:40

can go and just close this and I can go ahead and right click in my gam HTTP and

39:46

send a request right which now it is sending the request but we are in the context of a debugging session which is

39:52

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

39:59

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

40:07

there's one thing that we're missing so far and that is a way to represent the

40:12

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

40:19

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

40:27

already defined this one well by default we get this map get that all is doing is just returning this hello word right

40:33

which is a simple string but in our case we may want to have multiple properties that are associated to our games that

40:39

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

40:45

what is known commonly known as a data transfer object now data transfer object or dto is an object that carries data

40:52

between processes or applications it encapsulates data in a simple and standardized format that can

40:58

be easily transmitted across different layers of an application or across different applications so let's see how can we go

41:05

ahead and Define a dto to represent our Gams so let's go ahead and just close

41:11

this file and for this we're going to be using actually the solution Explorer down here solution Explorer let's open

41:18

up that uh and we're going to be using this anytime we want to create either folders or files for our project because

41:24

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

41:31

folder we're going to name this folder dtos now keep in mind that other folks

41:38

like to name this folder contracts as opposed to dto which is totally fine because a dto can be considered like a

41:44

contract between the client and the server because it represents the shared agreement between client and server

41:50

about how the data will be transferred and used so if you want go ahead and name these contracts that that would be

41:55

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

42:02

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

42:12

okay now why why are we using record types here as opposed to a standard class well the thing is that by default

42:18

records are immutable meaning that once their properties are set usually at the time we create these records they cannot

42:25

be a changed right and this immutability is a perfect fit for dto uh because they

42:32

typically carry data from one point to another without the need for modification and on top of that records

42:38

reduce the boilerplate code that is typically associated with class definitions intended for data holding

42:45

like DTS as as you're going to see you can Define these records with just a single line including all the properties

42:51

which simplifies the code base and makes it much more readable and it has I mean record types have many other benefits

42:58

but these are the main ones that I see that are very useful for dtos right so let's go ahead and let me

43:04

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

43:10

file structure so let me open up my explor again remember that this is under our DTS directory and because of that I

43:15

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

43:22

either type here just. dto or you can use this this liel over here you can click on that and you can select the

43:28

option that says change namespace to gam store. api. dtos right so that's going to make make it so that it matches right

43:35

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

43:41

actually need this coolly rases all we want to do is just open parenthesis here and here we can start declaring our

43:47

properties the first one is going to be our ID that's going to be an INT int ID

43:53

and then the next property is going to be a name uh let's follow that with a gener so

44:00

gener is like is it sports racing role playing whatever kind of game we're dealing with we also have a price and

44:09

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

44:18

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

44:25

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

44:32

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

44:39

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

44:47

start writing the next few lines just keep in mind that our API is going to be evolving across this tutorial right so

44:53

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

44:59

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

45:05

better implementation and in that sense what we're going to do here is to define a very simple list of games in memory

45:12

using our dto class we're going to see how to implement the different HTTP methods along or around that in memory

45:20

lease later in the tutorial we'll see how to transition from that me in memory lease into an actual database

45:26

so what we're going to do here is just perhaps just after the the definition of our web application object over there

45:32

we're going to declare here a simple list of our game dto right and notice that by selecting game dto BS code

45:40

automatically added a using a statement over here game store. api. dtos right so that it just did it by by itself and

45:48

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

45:55

to Define that list right here now I have already prepared a small list of

46:00

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

46:09

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

46:15

is going to be Street Fighter 2 the generator is fighting now we have the price here and we have an M here because

46:22

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

46:27

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

46:34

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

46:43

playing here's the price here's the date and lastly we have another of my favorite games FIFA 23 with ID3 Sports

46:50

here's the price and finally the release date all right now how how do we go

46:56

ahead and actually uh Implement an API that can return these games over here

47:01

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

47:08

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

47:14

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

47:19

going to be the path under which this endpoint is going to be located right in

47:25

this following proper rest practices we should name this as games because the

47:31

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

47:38

in plural because that is the way to address the group of resources you're going to be dealing all right it's very

47:44

important to keep those conventions like that now after you define that pad what

47:50

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

47:57

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

48:03

games so this land Expressions just says that we're going to be returning whatever is in the games list over there

48:10

and really all that's all you have to do and this is really why this type of API

48:16

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

48:22

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

48:29

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

48:37

net run and then what we want to do is just go back into games. HTTP and what we can do is just modify

48:44

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

48:52

going to just copy games over here slash games and that's pretty much it so I'll just

48:57

right click I'll do send request and as you can see on the right side we get a

49:04

200 okay response so it was a success and down here we have the actual games

49:09

so notice that we have here Street Fighter 2 we have Final Fantasy 14 FIFA 23 it's all there and then like I

49:15

mentioned before this is a Express in Json right so espinet core took care of

49:21

Transforming Our C objects serializing them into Json a as you can see right

49:26

there all right so yeah so that's our get endpoint and then now let's go ahead

49:31

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

49:39

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

49:46

so that we can keep track of what exactly each of these endpoints is expected to do I'm going to add a little

49:51

bit of a comment here so this would go for a get get games right so whenever somebody

49:58

goes into get games uh this is the that's is going to respond okay just as a little bit of documentation now what

50:04

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

50:10

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

50:17

let's do the documentation first it's going to be something like games slash a one for instance how do you represent

50:23

that so app mapet okay and so again we start with

50:28

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

50:36

this what is known as the pattern we can specify with this corly Braes we can introduce a kind of um the variable that

50:44

we're going to be using to receive that ID right so that goes in the row template and then in the next parameter

50:51

for the Handler what we're going to do is now not receive just an empty argument list but we can actually

50:56

receive that ID that we specified there with the exact same same name int ID

51:01

right and then this leads us into the actual execution that we want to to perform here so what we want to do in

51:08

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

51:15

to find and then we will do game where game. ID equals the and just like that

51:24

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

51:31

terminal close this go back to G HTTP and what we want to do now is to H just

51:36

add another request here now to separate your request in this file what you want to do is just introduce these three

51:43

pound signs and then you can add your request and I'm going to copy the first one down here notice that because we

51:50

have this three pound signs we also get the send request link over there which means that it is recognizing it so we

51:55

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

52:01

here I'm going to um just append slash and then we want one of the games so

52:06

let's do number one and then let's right click let's do send request and on the

52:12

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

52:18

right so yeah very simple and very very similar to what we did before right so

52:24

let's close this and let me control C stop my server back to

52:29

Broncs before we move forward uh notice how we keep using the proper rest notation as we Define our end points

52:36

right so for instance in this case when we did games by ID we prefixed everything with the name of the resource

52:42

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

52:47

like get games right that will not be correct it has to be games or you cannot even say something like um games

52:55

uh games by ID and then something like this right that will make no sense so to

53:01

follow proper reson notation you always start with the grouping or the the term that represents the group of resources

53:07

and then you follow when you want to specify something or find something by ID you followed by with the IDE of the

53:12

identifier or of that resource right so this is the right way to define resources in rest if you're not doing it

53:18

this way you're not doing res right so now let's move forward to the creation

53:24

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

53:31

need to Define how is that or what is going to be the representation of those resources we're going to be receiving

53:37

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

53:44

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

53:50

our Explorer over here and we are in solution Explorer and what we're going

53:55

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

54:02

this one is nam going to be named create game dto all right and then once again

54:09

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

54:14

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

54:20

can pick whatever makes it this case change name space to Gam store. api.

54:25

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

54:33

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

54:40

difference I'm going to paste those over here and the difference is that when we

54:45

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

54:52

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

54:58

we STI with the name the gend the price and the release date now this the is

55:03

going to be changing later on in this tutorial this is just an initial version but for now notice how the contracts

55:09

that we're going to be using either for returning data or for posting data into the API uh may be different right so

55:15

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

55:21

now that we have our create game dto let's go back into to pram Cs and we can

55:26

go ahead and Define our brand new endpoint so the endpoint is going to be for the Post Verve when somebody post

55:36

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

55:43

map post okay and of course it is when somebody post something into games and

55:49

in this case in our Lambda what we're expecting to do is to actually receive a

55:54

object object of the type of our dto the run new create game dto and let's just

56:00

name it this one as new game all right now what are we going to do in this case

56:05

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

56:13

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

56:20

inmemory Leist for so for that let's just do game dto G it's going to be a

56:27

new okay and let me open and close here so the first parameter here of course is

56:33

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

56:39

what we're going to do is just add a plus one to whatever count of games we

56:45

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

56:53

to be our ID then we go for for the name so that's going to be new game. name and

56:59

then we go for the generate so new game. gener then new game price and lastly new

57:09

game release date right so that's going to go ahead and complete the definition

57:14

of our brand new game and then let me scroll down bit we can do is just say

57:20

games. add our game right so the game is part of our list and lastly what we want

57:27

to do is return something back into the client to tell the client what was the result of the operation did it succeed

57:33

did it fail what happened and we can provide even more details and the standard in this case is to return a

57:39

2011 created response how do we do that so all you have to do is just say return

57:45

and you can use the results class right so this a this a buil-in class in infinite core results and then this

57:51

contains multiple prebuild responses that you can use so you don't have to manually specify the status of the

57:57

response so in this case we're going to say is created at Route okay and then we

58:04

use this because with this we can provide a location header back into the client so the client knows exactly where

58:09

to find the resource that just got created so how do we do that so the first parameter here is going to be the

58:15

the name of the route where the client can find that resource now we have not actually defined the name of that route

58:22

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

58:29

over there and just before closing this we're going to just do here dot with

58:35

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

58:42

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

58:49

game and then now and now we can use this exact same name down here

58:55

in our order in our return created by ad route get name get G and C is going to

59:02

take care of figuring out what is the route to to that endpoint right and to use it to build the location header to

59:08

return back to the client okay the next parameter I want to specify here what is

59:13

going to be the the value that needs to be provided to the get game route remember that get game receives an ID

59:19

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

59:26

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

59:31

that it has an ID and that ID is going to be game. ID the one that we

59:37

autogenerate last parameter here is going to be the actual payload that

59:42

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

59:49

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

59:56

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

60:02

this value so let me just copy this and let's go all the way up here okay before

60:09

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

60:17

going to be get game okay so now we can just copy this constant down here we can replace that

60:24

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

60:31

having this hardcode this all right so with that in place we are ready to go ahead and test our brand new post

60:37

endpoint so open the terminal and I'm going to just do net run all right so it

60:44

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

60:49

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

60:56

with no ID right it's just the endpoint games endpoint and then one thing you have to specify here is the content type

61:03

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

61:09

content type and the content type in this case is going to be application Json right and then uh in this case

61:16

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

61:23

define the payload of our of our game we're going to be Crea remember that the payload has to include a name general

61:30

price and release date as per our create game dto so back in HTTP here's HTTP uh

61:35

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

61:41

here's our first game so this is going to be as you can see it has a name gener

61:47

a price and a released right in Json format so we that in place and since our

61:52

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

62:00

the right side we are getting the expected 20 one created response over there okay and then down here we can see

62:07

the payload that represents the game that was created right notice that it has the id4 it's a fourth game in our

62:13

list and it not just has the payload down here but it also provides us with the location header right notti this

62:19

here here's the location header uh that ainet core created for us because we provide Ed the the right values for the

62:26

created at Route method that we us right and so and since we have this the client

62:31

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

62:37

go and say for instance let's say over here we can replace that and now we can

62:42

right click and send send request and now the client was able to query for that brand new game right there game

62:48

number four and of course if we execute the first request we should be able to see that we have total of four games

62:54

over here one two three and four here's the four games all right and yeah that's

63:00

it for the implementation of our get a let me just stop my server here and let's go back to

63:05

prcs so now we're able to query for games and create brand new games so how about updating existing games right so

63:12

for that of course we're going to be needing a a put endpoint but before that

63:17

just a before we need a brand new dto to represent the payload that the client should send when they want to update the

63:23

resource so let's go back into our cont shift e our Explorer here this is solution

63:29

Explorer right click on dtos add new file record and then this is going to be

63:35

named update game dto now we could certainly just use create game dto for

63:42

the same purpose uh but really the convention is to always specify a brand new contract or dto for every single new

63:49

operation because eventually things could change right it would it could be that you may need to do something

63:55

different for upd dates that is not needed for a creates and so I don't want to be messing with those contracts so

64:01

just keeping them separate one for each operation right so let's go ahead and

64:06

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

64:13

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

64:18

just that and with that dto in place let's go back into program. CS run that

64:24

CS over here and let's define our put endpoint so I'm going to move down here

64:30

let's go and do this so we can see better and let's define our app and by

64:35

the way let's define that this is going to be for a put into games right and so

64:41

app. map put in this case map put and then once again this is going to go into

64:48

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

64:55

replaced right put in here means replace resource with whatever I'm going to be send okay and then uh we are going to

65:03

specify two parameters in this case h is going to be inside our arguments Lambda

65:09

um the ID we need that ID that we just specified in the template and then of course the update game dto updated

65:18

updated all right now let me just check one thing yeah we forgot to fix name space over here

65:24

we should always have the the correct name space so let me do control dot here to change space to G store. api. dtos

65:32

all right and then what do we do about the body of this Bo so let's open up our

65:38

body for the Lambda right there and what we're going to do here is just H find

65:44

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

65:52

brand new representation right so so let's first find find the index of the

65:57

game so we're going to say index it's going to be games. find index and then

66:04

for the game where game. ID is it that we got as a parameter so that gives us a

66:11

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

66:18

create a brand new game dto right so let's open and close parenthesis and

66:26

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

66:32

have updated game. name updated game. gener updated game. price and updated

66:41

game that release date all right and so with that we have replaced uh the the

66:47

game in the list and last thing is to return something back to the client now the convention for an update is to just

66:54

return no content right so return results. no content and that will be

67:01

pretty much it for our put operation now uh you may notice that there we are not

67:07

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

67:14

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

67:20

and then we're going to go back and start refining these endpoints with whatever pieces we are missing okay so

67:25

for now just happy back so now we have our input defined let's go back into our

67:30

gamat HTTP and let's see how we can query a send a request for this put

67:36

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

67:43

request now let me just copy this the endpoint goes into SL games but

67:49

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

67:57

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

68:03

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

68:09

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

68:16

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

68:23

this first game just going to copy it and then down here I'm going to use that

68:28

for our put body now let's not forget to use content type application Json over

68:35

here and then let's paste that down here looks like I didn't copy it properly I'm

68:40

going to just grab it from my other screen there here we have and what I did

68:45

here really is just modify the title right notice that the initial title uh as we can see right here was um strict

68:53

Fighter 2 right price is $19.99 so I'm going to make a small change so that the

69:00

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

69:06

just $9.99 right those are the two changes that we're going to introduce into this game but just keep in mind

69:12

that putot is going to replace the object right that's the purpose of put replace the object completely so with

69:18

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

69:25

content that's the expectation that's good and then if you want to verify that things the the game actually changed all

69:30

we have to do is just go and query for game with ID one in the get so right

69:36

click Send request and on the right side we should be able to see that yeah indeed now it is a street fighter too

69:43

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

69:51

our server back to pron CS now before we move on into the last

69:56

operation the delete operation one thing that you have to consider here is that um er concurrency right what happens

70:03

with concurrency now now keep in mind that all the the thing that we're doing here is really a starting point towards

70:09

something we're going to be doing next but if you ever decide to just go into production with this in memory list of

70:15

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

70:20

list that we have over here and this list is not threat Save Right meaning that if you start getting multiple

70:27

requests let's say into put over here right you could go run into issues right

70:32

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

70:38

problems so don't do that in that case you want to be using something different than a Leist perhaps a concurrent back

70:44

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

70:50

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

70:55

much more interesting right and so let's go ahead and Implement our last endpoint and this is going to be our deleted

71:02

right so let's scroll down here and documentation this is going to be a

71:07

delete for the games pad and then we need to specify some sort of file right

71:13

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

71:19

this case just gains and then it has has to have the ID of course and then we

71:26

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

71:33

Lambda body over there and let's see what would we do for a delete but the delete is actually as you expect the

71:40

simplest thing to do all you have to do is just remove any any game that matches

71:45

that for that what you can do is just say games that remove all and then where

71:50

the game is game that I ID equals ID

71:56

that's all and then uh the expectation for the delete is again a no content

72:02

just like in the update case so you can do return results. no content that's all

72:08

it is all right so and well to test this very easy let's go ahead and run our

72:14

server once again the Run let's go to our file over here I'm going to grab the

72:21

location from the previous request and I'm going to just add here another

72:26

request down here now in this case it's going to be um delete into whatever part

72:33

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

72:39

number two right and so now before we delete let's confirm what we have initially right so right click at the

72:45

very first request we have three games right now one two and three we're going to be deleting number two Final Fantasy

72:52

14 so let's right click on let's close this and right click on our delete request send request it says no content

72:59

204 no content meaning this is successful so now we can go back and get our full list once again send request

73:07

and on the right side you can see that we no longer have a game number two so

73:12

we have one we have three we have two it is gone so our delis is working as aect

73:19

all right let's close this and let's stop our server and back into

73:24

prones now at this point our API is mostly functional however we have only

73:30

dealt with happy pads right so we still need to deal with a few unexpected scenarios for instance what happens if

73:37

we are not able to find a game right and let's try it out so let's go ahead and

73:42

run our server all right and now let's go back into games.

73:47

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

73:54

games one two and three that's fine now let's use our second request to request game number four right what happens if

74:00

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

74:07

getting a 200 okay which is already bad right because I mean there's no game why are we getting a successful result we

74:13

even getting a null response down here so this is this is just completely wrong

74:19

this is not what we should be returning there's a standard way to reply

74:24

for a situation where the resource cannot be found and that's what we're going to cover now let's close this and

74:30

let's stop our server and perhaps we can close a few of these tabs here to simplify our screen move this here so

74:37

let's head back into our get by ID get by ID method over here so this one over

74:43

here so first thing we're going to do is just to give a proper body to this uh to

74:50

this method so let's open C right there let's do this all right like that and

74:59

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

75:07

far gain equals games. find okay now what are we actually receiving from

75:13

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

75:20

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

75:26

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

75:33

not able to find game because of that what we can do is to alter the response to our endpoint here to return the

75:41

correct response depending on if we found the game or not so we can say is

75:46

well return we're going to say if game is null right so if it is null uh we're

75:52

going to return we're going to be using the results results class to return not

75:58

found right this a standard response where we're not able to find the

76:03

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

76:09

cannot just say game right because now we're returning two things right one

76:15

side we're returning an object of type I result and on the other side we're returning an object of type gain

76:21

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

76:27

the game into results. okay okay that

76:32

will make sure that for both cases we are always returning the same type of ey

76:37

result all right and yeah that that's pretty much it so if we run this once

76:43

again so let's run the API right so running it g. HTTP now let's try to

76:48

retrieve game number four once again request and you're going to see now we get the proper 404 not found there is no

76:56

null down here and this is the expected response when we're not able to find a

77:02

resource all right so yeah so that fixes the case of our um if our get by ID

77:10

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

77:17

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

77:24

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

77:32

is actually minus one so that's the response minus one we're going to say okay result return results. not found

77:41

now one thing to keep in mind here is that returning a not found for a put

77:46

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

77:53

terms uh if this is the absolute true of what you should return because another thing that you could do in this case is

77:59

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

78:06

we receive over here right and that's what many services do but many other services will just return and not found

78:12

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

78:18

cases now I do prefer this way of returning not found because in the case

78:24

where you H actually choose the other option where you create the resource you run into a bit of a problem when um you

78:32

move into a scenario when you actually have a database uh that is able to

78:37

create the the IDS for the resources by itself um and in that case if the ID

78:43

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

78:49

go ahead and just go ahead and create a resource uh the the database will go

78:54

ahead and create the resour we whatever ID makes sense right so it's out incrementing usually right and that may

79:01

not match the ID that you specified here right so you get into a weird situation of what do we do about that that

79:06

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

79:13

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

79:20

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

79:27

we're going to go ahead and try to do a put for let's say game number five which

79:33

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

79:39

getting now a 404 Note file so our new logic is working awesome so let's close

79:45

this and let's stop our termin and back to pram CS now what about our delete

79:51

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

79:57

doesn't really matter right because we're just removing whatever we can find that has the specified ID right and

80:04

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

80:10

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

80:16

long as a resource does not exist anymore after invoking the delete operation all right now uh well now we

80:24

have our endpoints pretty much uh implemented right at least the basic behaviors and then one thing that maybe

80:31

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

80:37

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

80:43

somewhere else to keep our PR CS as clean as possible so because of that what we're going to do is the following

80:49

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

80:54

create a brand new directory in solution Explorer so gam store. API right click new folder let's name this folder

81:03

endpoints all right and in the new endpoints directory we're going to right click and we're going to add a new file

81:08

unless this is going to be a class and this class is going to be named games and

81:13

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

81:20

our name space so it is st. api. endpoints right there and let's class

81:26

this now this is going to be what is known as an extension method as extensions class or I mean going to be a

81:33

static class that's going to have extension methods which are going to be H static and the idea of this class is

81:38

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

81:43

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

81:50

actually works so first this class has to to be static okay so we can have our static sanction methods inside and then

81:57

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

82:04

start with this const and the list that we have here let me copy this we're

82:09

going to copy that over here all right and then let's make sure that we import

82:14

spaces I'm going to do control dot on game dto to use G store. api. dtos all

82:20

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

82:27

modifier for the type of access that we should have for this games list so in

82:32

this case this is going to be a private list all right and we have cool races here because it is suggesting that we

82:39

should make this field read only which makes sense uh because uh even when we may be adding and removing methods into

82:45

this H adding or removing games into this list we're never going to be reconstructing the entire list from

82:51

scratch right that's never going to happen and so because of that we can make it readon right now it is a readon

82:58

list okay now is have squiggles here uh because we are declaring an instance

83:04

member in what is really a static class right this static class so because of that we will have to make this list also

83:11

static and really everything here is going to be just static now with that in place we can move forward to actually

83:17

declare our extension me like I said this is a method that is going to extend the functionality of an existing class

83:23

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

83:30

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

83:36

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

83:42

that type is going to be web application all right that will allow whoever calls

83:47

this method to just chain another call into uh into another extension method that is also extended with web

83:52

application if they want to now the the name of this method is going to be map

83:58

games end points and then this is going to receive web application and let's

84:04

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

84:10

that turns this into an extension method so now our method is going to show up as a new method of the web application

84:16

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

84:22

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

84:30

here right so our method looks like this map gain end points and we start adding

84:36

all the map gets map post map put and map finally since we are returning a web

84:44

application object we should just return up okay and uh yeah that will do it for

84:51

our map gain Senter end points uh extension method right we just return app at the end with that in place we can

84:57

now go back into pram Cs and we can clean things up so we can go ahead and

85:04

pretty much remove everything between app and app. run or we can just get rid

85:09

of all of these and all we have to do now is say app. map games

85:15

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

85:21

remove on usings like that so that's all we have now in our prcs and now we have

85:28

our everything that relat is related to endpoints in games end points. CS right

85:34

now it it is possible to forther refactor this of course you should do that but in this story we're not going

85:39

to go that deep into refactoring we want to move forward to another set of very important topics regarding R cpis and

85:46

one of the topics here is the fact that if you notice we have um we have this

85:52

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

86:00

byid and then we have it for every single endpoint we have games gam games all over the place so can we do

86:06

something to improve that we certainly can and to do that what we can do is just take advantage of something that is

86:13

known as a group Builder right so we can create a group that defines common things across all the endpoints so that

86:19

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

86:25

is say well our group equals app. map

86:30

group okay and in this map group we can say that okay so all of my routes for

86:35

this specific set of endpoints are going to start with games right everything starts with games and with that we can

86:44

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

86:51

to replace app here with group group and then the same thing for every single

86:56

method here so group and then group and group okay and since we have changed

87:03

everything into that group variable we probably want to also go ahead and return that group down here as opposed

87:08

to the app now group does not map the web application so we'll have to change the return type into route group Builder

87:17

right so let's go all the way up and let's change from web application into route group

87:23

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

87:28

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

87:35

right still goes into slash games like this but it's going to be because the

87:41

get is changed into the group that we created up here all right so for the second one we can remove games right

87:48

it's just SL ID and same thing here a post is just is going to be like that

87:54

for put it's going to be like this and for delete same idea all right so that's

88:00

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

88:05

group Builder Okay and then well let's make sure that things are still working properly so I'm going to just run the

88:11

API and let's just check that we can go ahead and engage that HTTP we should be

88:16

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

88:21

more think our post right click Send request and it is working as expected right so it's all good awesome now the

88:30

next thing that we should work on is well what happens if we receive invalid inputs right so in this case like for

88:37

instance in the post case this one over here what happens if somebody posts um a

88:42

payload with without a required element right for instance we should not be able to send and let me scroll down here we

88:48

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

88:54

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

89:01

let's hit send request and let's see what happens right so notice this so the

89:06

resource got created so 2011 no problem but now not notice this we got a null in

89:12

the name so the API allowed us to just create an invited resource and that is

89:18

not good so in this case what we should be returning is really a bad request right uh because it is a validation

89:24

error and the input is not correct so we have to do something to account for those cases right so let's close this

89:30

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

89:36

now if you go down into my post over here right uh well there's a couple of

89:42

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

89:50

receive the post request we could Su something like well if uh stream. is n or mty perhaps uh new game. name right

90:00

uh we could go ahead and say well return we can do results. bad request right and perhaps

90:07

we can even add a a little message here that says name is required right so that

90:13

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

90:19

let's go back to G at http click here send request and that works right so now

90:24

we are getting a bad request which is much better and we even have a little message down there so that's okay

90:31

however of course uh this is going to start becoming a little bit uh challenging right because uh if we let's

90:37

go ahead and stop the server server go back to games endpoints uh because name

90:42

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

90:48

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

90:54

request right so this is not the best approach so what we want to do is to introduce some sort of proper validation

91:02

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

91:09

that you can use in net to do validation and that is by using data annotations so

91:14

let's H let's actually undo this we're not going to be using this really right

91:20

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

91:28

is to use this concept of data notations so data notations are nothing more than just attributes that you can apply to

91:33

your properties and that can Define what is expected of these properties for

91:38

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

91:45

dot here to import the system component model that data an notations name space and even more I'm going to say that uh

91:52

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

91:57

nothing more than that so we can do string length of 50 like that okay so

92:06

with that any anywhere we use this great game dto that validation should be automatically applied that's the idea

92:12

behind this okay and then um for the gener let's do something similar but

92:18

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

92:25

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

92:31

even more than that perhaps we can say that the price should be in a range of

92:36

one to 100 that should be good enough for a price we don't have video games that are more than

92:42

$100 um of price I mean that would be that would be crazy um and yeah that's

92:48

pretty much it so that defines the data notations for our H for the creation of

92:53

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

93:00

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

93:08

this H post request request it still is not doing the validation right so notice

93:13

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

93:20

the in the older core MBC framework but when you do minimal apis you need a little bit of

93:25

more support and at this point what you want to do is to use a new feature

93:31

called endpoint filters endpoint filters is a feature that comes with minimal apis that allows you to validate what's

93:36

coming in into your into your endpoint and do some sort of validations around it right now and let me let me just

93:43

close this and let me stop my Ser now we could use endpoint filters manually

93:49

ourselves uh but there's Act a better way so there are nuget packages that already wrap the right endpoint filters

93:56

that can tie directly into the data notations that we're using here so that we can easily enforce these validations

94:02

right so what I want to do is to show you a nugget package that you can use to automatically perform the validation so

94:08

let's let's actually go into let's go into nuget.org and by the way if you're

94:13

not familiar with nouet nugget is the is pretty much the package manager for net and so there are hundreds and hundreds

94:20

probably Millions well thousands or millions of n packages are already available that can simplify many things

94:26

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

94:31

package let me show you here so I'm going just type here minimal apis. extensions you search for that this is a

94:38

free nugget package well everything is free really here uh open source nugget package that is able to help us in this

94:46

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

94:53

let's go back into vco so I'm going to open my terminal and I'm going to just paste

94:59

that line so package minimum API extensions in this case I'm using version

95:05

0.11.0 and hit enter all right and so at this point if we take a quick look at

95:11

our let's see gam store. API project this is our project file CS BR notice

95:17

that now we have our first package reference this means that now our project is able to use any of the types

95:23

classes defined inside that net package and because of that we can do the following now so let me go into G

95:30

endpoints now under our post over here we can go ahead and say just before

95:37

ending we can say dot with parameter validation which is one of the methods

95:42

provided by that n package okay and just by doing this the appropriate endpoint filters are going to be applied and are

95:49

going to recognize this data annotation that we specified in great game video so now if we just go ahead and uh run our

95:57

API okay it is running back to games at HTTP let's execute our incomplete

96:02

request send request and notice that not only we get our bad request as we should

96:09

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

96:16

more validation errors occured we have a status 400 and we it even tells us exactly which field uh is

96:23

missing right and so and this is this is very nice and in fact this is actually

96:29

tied to the proper RFC that you can see over here uh which is the right way the standardized way to report errors back

96:35

into clients so that clients can easily read these errors and act accordingly right and we were able to do all this

96:41

just by using one nouet package right now if we go back into the code uh one

96:48

thing that you should realize is that um you can can do this parameter validation not just for one endpoint you can

96:53

actually apply it for all of the endpoints all of the endpoints by using your grout route group right remember

96:59

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

97:06

it here we can say dot with parameter validation and now these validations apply to any of the endpoints that are

97:12

going to be receiving one of these uh DS that have data notations right and in fact we are doing validations right now

97:19

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

97:28

just going to go ahead and and copy this because it's pretty much the same validation we're going to apply right

97:35

there same validations and make sure that we import the right in space and now both create and update should get

97:42

validated so let's go ahead and run our API let's make sure that all of these validations are working properly right

97:48

so let's go back into G http so we already verified H the create for

97:55

an empty name now what happens if we try to do a very long name right so Minecraft Minecraft Minecraft big name

98:01

like that so I'm going to right click here send request okay let's see notice

98:08

the error now the field name must be a string with a Max a maximum length of 50

98:13

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

98:23

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

98:30

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

98:37

price of 119.99 right click Send request and as

98:43

you can see over here the field price must be between one and 100 so that's

98:49

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

98:56

the name from the put and let's use a valid a ID let's do id2 right click and

99:02

request and as you can see once again we get a bad request my request over here

99:08

and uh if you go down there yeah you can see the name field is required so yep

99:15

it's all working as expected so now we have properly validated endpoints all

99:20

right so let me go ahead and just stop our server okay and uh with this in

99:25

place I think it is time to start moving away from this ink memory list of resources and actually introduce a

99:32

proper database for our res API and to do that we're going to be using a very

99:38

handy framework that is part of net that is known as Entity framework core so let's switch briefly into slides to

99:44

learn more about Ed framework core and why it's going to be super useful for our development here in this section you

99:51

will learn about the object relational mapping technique and how Entity framework core can help you write code

99:58

that interacts with your database without having to learn a new language at this point we want to add database

100:05

support to our res API so that all our data is persisted beyond the lifetime of

100:10

the application so whenever a request to create a game is received in our API we

100:16

want to create that game in the database and when the client requests a list of games we want to query that list also

100:23

from the database however there is a problem the database does not speak the same

100:29

language as your esinet core API your API is coded in C but your relational

100:36

database server only understands the SQL language that means that to fulfill that

100:43

request to retrieve games your C code needs to translate the API request into

100:49

a carefully crafted SQL query and then send that query to the database

100:54

server the database server executes the query and then your C code has to read

101:00

back any resulting rows and translate them into a corresponding API

101:06

response this presents a few problems as a c developer you now need to learn a

101:12

completely new language SQL in order to graft the required queries and you need

101:19

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

101:26

code whose only purpose is to translate things from C to SQL and vice versa and

101:32

of course deal with unexpected errors talking about errors this approach is

101:37

error prone since it's very easy to make mistakes when mapping things from one side to the other and you need to

101:44

manually keep your C models in sync with the corresponding database tables which

101:49

can be quite challenging this is where object relational mapping techniques or orm can make a big

101:57

difference but what is orm well going back to our Spotify example imagine your

102:04

application has been created using an objectoriented paradig and therefore it

102:09

includes objects to represent songs artists and playlists and if you're working with a

102:16

relational database server there's a good chance your database will have corresponding tables for each of those

102:23

objects now instead of having to write custom code to map these objects to

102:29

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

102:37

your program can keep working with objects while another component an object relational mapper takes care of

102:43

transforming objects to tables and vice versa so in essence object relational

102:49

mapping is a technique for converting data between a relational database and

102:54

an objectoriented program and as you can imagine it brings many benefits to

103:00

application developers and fortunately snet core includes a great orm framework called

103:06

Entity framework core so what is Entity framework core it is a lightweight

103:13

extensible open source and crossplatform object relational mapper for.net Entity framework core will sit

103:20

between your res API and your database server besides mapping your donet objects to database tables it will

103:27

translate your C data access code into seq statements that the databas server

103:33

can understand and it will also translate any resulting data from the database into objects that your API can

103:40

easily manage using Entity framework core in yournet applications brings in

103:45

multiple benefits there's no need for you to learn a new language you can perform all

103:51

data access tasks using your familiar C language the actual data access code

103:57

that you need to write is minimal since Entity framework takes care of most of it in fact you can use language

104:04

integrated query or link to perform most of your database queries there's tooling

104:09

available to keep your C models in sync with your database tables so you don't need to do this manually anymore Entity

104:17

framework can keep track of the changes made to your C object instances at run time so it knows what changes to send to

104:24

the database when it's time to persist the data also Entity framework cor supports multiple database providers so

104:30

you can use your same C models with other relational databases if needed

104:36

let's now see how to use Entity framework core to add database support to our game store R API the first step

104:43

towards adding database support into our API is to define the class or classes

104:49

that are going to represent the data model model of our application now could we just go ahead and use our dtos for

104:56

that um you could try to do that but in general that's really a bad idea remember that the dtos represent the

105:03

contract between your API and the clients right and that should rarely

105:08

change however what we want to Define now is the data model so this ties directly into the database tables that

105:15

we're going to be using in in our database and we want to have the flexibility to change those tables and

105:20

to lay them out in a relational structor that may not match those contracts those DS that we have already defined okay so

105:28

because of that and to have this flexibility we want to keep those separate right so let's not touch the

105:34

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

105:40

going to name a new folder is going to be entities okay the entities are going

105:47

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

105:52

going to be a class and this first class is going to represent not our gains but

105:58

actually our game generous because in our database we don't want to just store simple strings

106:04

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

106:10

generous and then have a relation between our games and our generes so let's define first our gener table for

106:18

our gener entity right there okay and for this class let me collapse

106:23

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

106:32

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

106:39

ID and this the second one is going to be string the name now we do have a

106:46

small warning here right for name that says notable property name must contain a nonn value when exiting the

106:52

Constructor what this means is that we have declared a variable that is not nullable right it's a simple string not

106:57

nullable string and yet we have not defined any default value for this for

107:03

this property right and so the compiler is complaining about this and it's asking us to to provide either provide

107:09

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

107:16

like something like this if you wanted to that will initialize the variable as an empty string another way to do it

107:23

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

107:29

nules in our G names right so a better way to do this is by actually using the

107:36

required keyword over here required and by doing that you're saying that whoever

107:41

goes ahead and constructs instances of gener we have to make sure that they provide a value for name when they

107:48

construct the object right whichever way they use to constru the object they have to provide a value for name right so

107:53

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

108:00

Define another entity in this case for the game so let's right click again on entities new file class and this is

108:07

going to be our game okay once again let's fix name space like that and let's

108:14

go ahead and define the properties for our game so if you remember we should have here an ID

108:21

then we should have our name so this is going to be our name and same thing we

108:26

want to define the name as required just like this it's required scroll down a

108:31

little bit and then we need to define the generate but now as you know we are

108:36

going to be using a relational model to associate the game with the gener uh

108:41

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

108:47

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

108:56

that is going to be connected to the ID of generate in the gener entity but we

109:01

also have to specify another property here of the type of gener itself so it's

109:07

going to be prop type generate and I just call it gener now this property

109:15

here may or may not be null right depending on if we decide to populate

109:20

generate when we read data from the database via at framework we may decide to populate generate or not right

109:27

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

109:33

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

109:39

this as a n just like that okay sometimes we have it sometimes we will not have it okay so that this

109:45

combination of two properties is what you do on Entity framework when you want to do an Association in this case a onet

109:51

to one relationship between game and gend right and so let's scroll down a

109:57

little bit more and then let's go for our price which we know it is decimal

110:02

that's a price and lastly let's go forour date only release date and with

110:10

that we have defined the two entities that represent our data model now it is

110:16

time to add proper Entity framework support into our API and for that we're going to be needing a nuget package so

110:23

let's go into nuget.org over here okay and we're going to be looking for a

110:29

brand new nugget package so let's search for microsoft. entityframework cord. SQ

110:35

light so SQ light is the database engine that we'll be using uh for this tutorial

110:41

okay it's going to be the first hit over here and keep in mind that you could be using really any other relational

110:47

database here like SQL Server if you wanted to but but for this tutorial I'm keeping it very simple with SQ light is

110:53

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

110:59

going to apply the same way to other relational databases like SQL Server the

111:04

only thing that changes really is what provider you use for Entity framework in this case we're going to be using the SQ

111:10

provider if you wanted to use SQL Server you can just change SQ for SQL Server

111:15

right and now you have a provider for SQL Server all right now this case let's go for

111:21

sq8 and I'm going to copy not the 900 preview let's go for a stable version in

111:27

this case I'm selecting 8 802 I'm going to copy this let's go back

111:32

into our code okay and let's just paste. net package this micros framework cod.

111:39

sqlite version 802 all right so now our API is ready to

111:46

take advantage of Entity framework now let's close this terminal and let's close close this so let's go back into

111:51

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

111:58

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

112:06

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

112:12

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

112:20

context right gain store context let's collapse this and let's just fix our name space very quickly change name

112:27

space to gain store. API that now G store context should inedit from DB

112:33

context DB context okay now notice that uh this imported Microsoft Entity

112:39

framework core this is a new imported name space uh but well you may be wondering well what is a d context right

112:45

so D context is really an object that represents a session with the database and that can be used to query and save

112:52

instances of your entities right so this is the intermediary so if you're familiar with either the repository or the unit of

112:58

work patterns um the DV context is a combination of both unit of work and repository right now to properly

113:06

construct your G your DB context you're expected to receive here you should receive what is known as DB context

113:12

options so DB context options of the type of your DB context in this case

113:19

game store context right let's just name these options okay and let's send this to the

113:25

next line let's send over those options to the base Constructor like that so

113:31

those options are the ones that are going to provide the gain store context all of the details about how to connect

113:38

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

113:44

representation of the objects that need to be mapped into our database right and so we know we're going to Beal with

113:50

games and with game generes right so because of that we're going to do the following we're going to declare prop

113:56

and it's going to be of type DB set so DB set of type of the actual entity here

114:02

so it's going to be game that's entity and we can name this one games okay now

114:10

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

114:18

any link queries a language integrated query queries uh against a d set in this case of type game will be translated

114:24

into queries against dat right and to provide an initial value for for games

114:29

what we can do instead of this is just point directly into H we can use this

114:35

method set of type game okay that's going to create our DB set instance all

114:41

right and just like this one we're going to create another one dbet of type J and let's name it

114:50

gems which is going to point to a set of type G our context is ready to go ahead

114:57

and map our objects our entities into proper database Tes but what we have to

115:02

do now is to tell our application how to connect to the database to our cite database using this

115:08

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

115:14

Explorer view over here and let's go into pram CS over there pram CS and

115:20

here's where we have to start using our Builder object to register Services right so down here what we can do is the

115:26

following first let's go ahead and Define a connection string so let's just

115:32

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

115:38

why what I really like sqlite all you have to do is specify here data source

115:44

equals and here you specify the physical PAAD into your database file right so in

115:51

this case let's just call it gam store. DB okay now here you could specify some

115:57

other pad in G store. DV if you don't want to have it directly um at the root

116:03

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

116:09

the project directory right but you can specify really any other physical pad so yeah that's a connection string and with

116:16

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

116:24

this case add SQ light and here we want to specify the name of our context the

116:31

one that we just created so game store context and then we want to pass in the

116:37

connection string okay now this is taking advantage of a mechanism that is known as dependen injection which we're

116:43

going to be talking about later in the tutorial uh but important thing to know is that because we are adding this

116:50

Services here Entity framework is going to take care of reading this connection

116:55

string right and then it is going to create an instance of our gain store context and it's going to pass in DB

117:01

context options over here that are going to contain all of the details that are in that connection string so that it can

117:07

connect to our database right and map the entities to tables however there's one thing that's not really ideal here

117:13

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

117:20

really wrong there I mean there's no secrets no credentials it is incredibly simple that is fine however it's still

117:26

not really great to have the code for the connection string right here because as you change into another environment

117:32

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

117:38

idea so you want to keep this information this configuration data outside of the order code base so to

117:46

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

117:53

system at this point we have hardcoded the connection string to talk to our database directly in our application

118:01

code however this is not ideal since eventually when we move the API to a

118:07

different environment like in a cloud deployment the connection string will be different and we would need to make code

118:13

changes which is not ideal fortunately there are better places to store

118:18

application configuration one of the most popular options in hnet core especially for

118:24

local development is the absen Json file which can store all sorts of

118:29

configuration information in Json format now the absens the Json file is what is

118:35

known as a configuration source and just like that one there are several other configuration sources supported in net

118:42

applications like command line arguments environment variables user secrets

118:49

and even cloud-based configuration sources like Azure key volt and the

118:55

great thing about this is that the SB net core runtime takes care of combining information from all available

119:01

configuration sources into a single configuration object that implements the ey configuration interface this

119:08

configuration object is easily accessible to your res API in such a way

119:13

that it doesn't really need to know where the configuration data actually comes from in this tutorial you will use

119:19

the apps Json file to store your connection string but keep in mind that

119:25

this is an acceptable option only because you don't need to use any credentials to connect to your SQ light

119:31

database if for local development purposes you are using a database server

119:37

instance that requires credentials please use the user secret configuration Source instead which is enabled by the

119:44

snet cord secret manager never restore any kind of credential in your

119:50

appsetting Json file let's now update our res API to read the connection

119:55

string from the appsetting at Json file let's see how to take our connection string out of program.cs and into our

120:03

upset. Json file so let's go ahead and open ups. Json and what we want to do

120:09

here is to introduce a brand new section that we're going to name connection

120:15

strings now this very specific element called connection strings is a well-known element of net meaning

120:22

that there are apis that are going to be looking specifically for this one word here Nam connection strings so make sure

120:28

that you type connection strings just like I'm doing right now now inside this

120:34

element you can introduce one key for each of the connection strings that you

120:39

want to introduce into your code now in this case we want one connection string for our game store database so I'm going

120:45

to just type here game store you can really type any name here but just make sure that is something that's related to

120:51

your database okay and then on the right side we want to introduce the actual value for this key now what value we're

120:57

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

121:04

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

121:13

like I said there are apis specifically designed to read these connection strings and let me collapse this for a

121:18

moment and what we can do now instead of just H reading the hardcoded word is use

121:23

the Builder object to get access to the configuration object over here which is the one that implements I configuration

121:30

and is the one that collects configuration information for every single configuration search that has

121:35

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

121:42

that we can just say get connection string then we pass in the name of the

121:47

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

121:52

copy game store and I'm going to paste that over here all right and that's

121:58

really all you have to do to read your a connection string fromjson now let's

122:04

confirm that this is actually working by placing a break point over here perhaps in l seven to see what value we read

122:10

into connection into const string so with that done I'm just going to go ahead and press F5 to start a debuging

122:17

session so F5 and this should be one of the first lines that is hit AS application starts all right so

122:23

breakpoint has been hit and so let's see what value we have ofation string as you can see data source equals. DV is

122:31

exactly the value that is being read from our set the Json file all right so

122:36

that is working perfectly which is great so let's just stop this session now at

122:41

this point our application is pretty much ready to talk to our database however the database itself this sqi

122:47

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

122:53

migrations so this is the Entity framework process that takes the different entities that make up your

122:59

data model and turns them into corresponding tables in your database

123:04

that are properly mapped to those objects and before we can do that we're going to need to install when additional

123:10

tool so let's go back into our nugget page over here and let's look for a tool

123:16

called net EF okay this is going to be the first hereit over here so netf is a

123:23

tool that you can use to do all sorts of Entity framework related task against

123:29

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

123:35

I'm recording this so I'm going to just copy this command and let's go down here

123:41

vs code let's open our terminal let's switch to gam store. API and let's just

123:47

paste that command okay so this line here is going to install netf this is not just a nuget package it is an actual

123:54

tool that you can use to execute a the frame related commands so I'm going to hit enter notice that this also installs

124:01

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

124:07

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

124:15

gallery and let's look for this package called microsoft. Entity Framework core. design now this package here is the one

124:22

that is going to be used to actually generate our enti framework migrations so let's go down here let's pick our

124:28

latest stable version 8.0.2 I'll copy this and back into BS

124:35

code I'm just going to paste that here hit enter and the package is now installed in our API project right let's

124:42

close this so now we're ready to generate our first migration now we have to decide where we're going to to

124:49

generate this migration if we look at our Explorer over here what we want to do is just to generate a folder under

124:55

our data directory we're going to place a new folder which is going to contain our migration which is going to have all

125:00

of these mapping code between our our C code in and database right so to do that

125:07

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

125:14

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

125:20

following command you can do netf migrations at initial create you can use

125:29

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

125:34

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

125:41

be under data like we said the data directory and then under that directory let's create another one called

125:46

migrations all right let's go ahead and execute this okay like I said it is built and then the migrations execute

125:55

now what actually happened here so if we go back into our Explorer let's close this now we should have under data as

126:01

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

126:08

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

126:13

first file initial create notice that this is going to have kind of um of

126:18

number that is somehow related to the date and time that we are generating this migration on right and so if I

126:25

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

126:31

called initial create and this going to have uh this the following methods so first is going to have this up method

126:38

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

126:45

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

126:51

database now if we go back into our up method notice that here is where the actual tables are going to be created

126:58

right so migration Builder create table here is the name of the table generous right because our DB context defines

127:04

this generous D set then generous is going to be created as a table and here are the columns for the table right

127:11

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

127:17

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

127:24

then with a type text for the name column right it also sets up a primary

127:30

key for the for the ID field in the generous table and then we move on into

127:36

the other table the games table over here that defines an ID name General ID

127:41

price and release date right with corresponding values for each column notice also the the ID is is going to be

127:49

an AO incrementing column meaning that anytime we insert a value into this table uh a brand new number sequential

127:56

number is going to be assigned for the ID okay then we also have our constraints here we have a primary key

128:02

for the games table on the ID column and we also have a foreign key that relates

128:08

our games table to the ID column in our generate table that means that every

128:17

every ID that we use for Generate ID in our gam table has to exist in the gener

128:24

St all right that's a foreign key constraint lastly we are creating an index for the generate Ed column in the

128:31

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

128:38

the database uh it's going to just go ahead and drop the gain table and then it drops the generous table in the

128:43

proper order all right so yeah so that is the migrations process and now our

128:48

codebase is ready I mean the codebase now knows how to go from nothing and into the actual database so what we have

128:55

to do now is to execute this migration so that it it's getting it gets applied

129:01

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

129:07

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

129:15

command is going to be database update so let's hit enter so net Entity

129:22

framework is going to locate that migration code and it's going to execute it against our machine right away so

129:27

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

129:33

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

129:41

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

129:47

of what's migration migrations have already been applied into your database right that's how Entity framework knows

129:53

what is missing from your database if you add new migrations later right so that's the E migration history table now

129:59

if we keep going down we're going to see that here's where Entity framework Noti

130:05

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

130:10

later it goes ahead and creates the gner table as you can see creates G table and

130:16

then we keep going down and we will go ahead and create our games table right

130:24

here right and then it will end up creating the indexes and finally it sets

130:30

a brand new value into EF migration history for the brand new migration that we just execute right so that happened

130:37

seems like it was a success now how can we actually take a look at that database and make sure that it got actually

130:43

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

130:49

we have a brand new gang store. DB file over there right now the reason while

130:55

this file which is a file for our sqli database got created directly under our game store API directory uh is because

131:01

of how we Define our connection string right if we go back to abs. Json I'm going to close this remember that we

131:07

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

131:14

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

131:21

create a that would place a database into that DV deer under your proct directory uh but just make sure that uh

131:28

I'll be aware that you have to create this directory manually before doing that uh otherwise entity will not be

131:33

able to create your database right now since this just for local development I think it's just fine to keep the databas

131:39

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

131:44

from your git comit right in on Gore so that the file does not get checked in

131:50

right so now we have our H file over here but how do we actually get into it now remember that we installed this

131:56

skite extension for BS Cod that means that we have the ability to pick into that database and to do that let's just

132:03

right click in game store. DV and let's use this very first element over there that says open database click on that

132:09

and by doing that notice that a brand new Explorer showed up over there on the left side SQ Explorer so that is going

132:16

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

132:22

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

132:29

with an ID name gener price and release

132:35

date there um lastly we also have like I mentioned we have our EF migrations

132:41

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

132:47

you just right click cck on the EF migrations and we select show table that's going to show us the current set

132:53

of values inside that table as you can see this just one value over there and it even keeps track of the version of

133:00

Entity framework that we're using so far all right so yeah so our our database

133:05

now exists and our application is ready to start start working with it now let's

133:11

go ahead and close this and let's go back into our file explorer now one

133:16

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

133:23

applying any missing migrations when the application starts that way we don't have to run the Entity framework command

133:30

to update the database every single time that we add new migrations so let me show you how to add some some of this

133:36

code so that the migration just happens as soon as as application starts all right so on our data deer and let me

133:43

actually switch into solution Explorer now under our data deer I'm going to right click and add a brand new file

133:50

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

133:57

an um an static class to hold a brand new extension method so let me let me

134:03

now collapse this oops let's just go back to the file right here okay so

134:10

let's fix our namespace contol dot let's fix it to gamestore api. dat like I said

134:16

this is going to be a static class because we want to put an extension method here and let's introduce a brand

134:21

new method here that we're going to name going to be static because it is extension method migrate DB okay and

134:29

this method is going to extend the web application object application class all

134:36

right and what we want to do here is to go ahead and migrate the database so

134:41

there are API in the framework to go ahead and migrate your database however everything that has to

134:46

do with our database needs to have an sculped Lifetime and we're going to be talking about dependence injection and

134:53

these lifetimes in in a moment uh but for now what we need to know is that we cannot just access the DV context

135:00

directly we need to provision a scope that allows us to actually start

135:06

interacting with the database right so let me show you how to do that first we're going to be getting an instance of

135:11

a scope so to do that let's do this using bar scope equals uh

135:19

services. creat scope right so that gives us a scope and let's see what type

135:24

is is this is an i Services scope right that we can use to request the service

135:29

container of ainet cord to give us an instance of some of the services that have been registered in the application

135:36

now remember if you go back into program. CS over here pram CS we have

135:42

executed this line here right at SQ light this this line here is going to register our game store context in the

135:50

service container right meaning that aset core knows about the type and is ready to provide us an instance whenever

135:56

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

136:04

equals scope service provider. get required service what service we need we

136:11

need the game store context service Okay

136:16

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

136:22

use our DB context to get access to our database and from there we can access

136:29

the migrate method over here which by the way imported a brand new namespace at the top over there Microsoft Entity

136:35

framework core all right and with these few lines we are now ready to execute

136:40

migration on Startup now all we have to do is go back into PR Cs and invoke that

136:47

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.

136:54

migrate DB right we can use this method because it extends our web application

136:59

uh object over there all right now to verify that this actually works what I like to do is just to well delete the

137:06

database right delete the database and the application when it starts it should go ahead and recreate the database

137:11

automatic right this is one of the reasons why I like to use SQ light for learning purposes because it's very easy

137:16

to use right click on the V here and delete the database right yep delete

137:22

it's gone okay now let's go back into our terminal over here going to clean

137:28

this and I'm going to go ahead and do net run and let's see what

137:36

happens as you can see all of the all of the statements uh go ahead and perform

137:43

the migration executed as you can see over here all of the statements executed just before stting the application and

137:50

gam store. DV is right there regenerated all right so yeah that work just fine

137:56

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

138:01

just stop my server for a moment is having so many statements every time the application starts right because from

138:08

here on any time the application starts Entity framework is going to be logging whatever is doing to our database if

138:13

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

138:20

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

138:26

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

138:34

can do is to um add just one more entry into this section login which is the one

138:41

that configures login for our application we can add one more entry to change the login severity of one of the

138:49

elements of our application so for instance in this case if we go back into the terminal right for instance all of

138:57

these statements that says hey I'm executing this command here and this command there right uh this I think

139:03

that's just T BS like all also here but all of those statements are coming from this one name space look at this

139:09

Microsoft Entity framework code. database. command so we can say we can do is say hey uh for anything that comes

139:16

out of the Microsoft framework code. database. commanding space please only show me warnings or errors right or

139:23

something critical but do not show me just information messages right these are all info as you can see on the left

139:28

side these are all informational messages what I'm going to do is just copy this let's see if we can

139:38

copy close this and I'm going to add an entry into here to configure a different

139:43

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

139:52

and by doing that I'm saying hey I only want to see either warnings or errors or something critical but not anything that

139:58

is really less severity than that okay so if you now go back into the terminal

140:03

and let me actually open my Explorer I'm going to delete the database once again let's see what happens different this

140:09

time so I close this let's clean our screen and let's do net

140:15

run notice that now the output that we got here is is way different right there is no mention of all of these commands

140:22

that are executing in there all that we are going to see here is this line here that says applying migration something

140:27

something and then if there was any problem with that migration or with any of the commands it would show up here uh

140:33

but otherwise the console it is just very clean right there's not much going on there so doing this is something

140:40

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

140:47

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

140:54

let's go back to our file explorer now as you know we have this concept of game

140:59

categories in our application right so things like sports racing or playing and all that and for those values that are

141:06

which which are pretty much fixed across the application we're not going to be creating apis to to create or modify the

141:12

categories we're just going to go ahead and populate the categories when the application starts right and to do that

141:20

we can use a very simple process of data seating that we can introduce directly

141:25

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

141:33

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

141:41

method just under our latest DB set and let's let's go ahead and overwrite we

141:47

want to overwrite the on model creating method this one over here on model creating all right so let's scroll down

141:55

and this is one of the methods that going to be executed as soon as the migration is executed right so when you

142:02

execute the migration this code over here is going to execute so this is an opportunity for us to do things that

142:09

slightly modify the model according to our needs and one of the things that we can do here is to populate some very

142:15

static data right now I'm not going to I would not do this for data that requires much more complex operations right this

142:21

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

142:27

what you have to do is just say model builder. entity and then the type of entity is generate and then we're going

142:35

to be using the method called has data right so this is going to make sure that

142:40

whatever data we introduce here has to exist when the migration process

142:45

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

142:52

gener so for instance I can say new and then I'm going to say well ID equals one

142:59

and this is going to be our name equals and the first category is going to be

143:05

let's say fighting all right so there we have our first element and let's go

143:10

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

143:17

here now we have um five categories that

143:22

we can work with right so fighting roll playing sports racing kids and family feel free to use less or more of this as

143:29

as you want but yeah so just by having this code here all of these H these five

143:35

categories are going to be created as the the migration executes so now for that to work we of course need to add a

143:41

brand new migration right because otherwise Entity framework doesn't know that it needs to map these to the

143:47

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

143:56

add and now we want to use a new name for this migration so let's say seat JIS

144:02

all right and once again the output output here is going to be under data

144:09

migrations right let's go ahead and hit enter all right migration completed let's see what happened on our Explorer

144:16

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

144:23

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

144:30

then here the migration Builder is executing the insert data method over there to go ahead and into the generous

144:37

table is going to insert these five values all right so that's that's all we

144:42

have to do and for the down method you will go ahead and delete all of those values that you got inserted all right

144:49

and once again like I mentioned I would only do this for very very simple data that does not need to interact with any

144:54

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

145:01

you're applying the migration right so only for very simple stuff and static data that is not going to really change

145:08

so if we go ahead and run the application now right so net run run

145:14

application okay notice that the new migration got applied over there see generous got applied and if we go into

145:22

our database okay let's collapse this let's go into our gam store. DB actually

145:28

SQ Explorer if we go ahead and right click on generous I'll say show table

145:34

let's see what we have let me collapse this let me close that and that as you

145:40

can see here we have our five generates now as part of the actual tape right so

145:45

they're right there is live data that we can now use in our application all right

145:51

so that is complete let me go ahead and just stop my server now we are approaching the moment where we actually

145:57

need to start changing our res API to take advantage of our new DV context and

146:03

all this Entity framework stuff but before we can do that it is very important to understand this concept of

146:09

dependency injection because remember for MCS we are using dependence injection to register this the the game

146:16

store content into ainet core but what does that registration means and what is all of this depend injection concept

146:22

about so let's switch to slides so we can better understand the concept of dependen injection in this section

146:29

you'll learn about the dependen injection design pattern and the multiple benefits it brings in to your

146:36

applications to understand what the pendis injection is let's start by looking at two classes my service and my

146:43

logger my service uses the log this method meod of my logger to log messages

146:49

to a file anytime my service performs an important operation since my service

146:56

uses some of the functionalities of my logger like the log this method we say

147:01

that my logger is a dependency of my service now in order for my service to

147:09

start using my logger it creates an instance of my logger in his Constructor and after that it can start

147:16

calling the lock this method at first glance it doesn't look like this presents any problems but consider what

147:23

happens when the authors of my logger decide to slightly modify it so that a

147:28

new my file writer object needs to be passed on this Constructor because that's where the output file is now

147:34

defined the required changes look simple to implement but they reveal a few

147:40

important problems my service is tightly coupled to my logger in such a way that any any

147:46

time my logger changes there's a need to also change my service as it happened

147:52

here when the Constructor started requiring a my file writer instance my

147:57

service needs to know how to construct and configure the my loger dependency

148:02

like is the case here with the my file writer object which needs to be configured with an appropriate file to

148:09

send the output lcks this makes it hard to test my service since unit tests

148:15

won't be able to mod or stop my logger an output. log file will always be

148:21

created which would slow down tests and this assuming that the test have access

148:26

to a place to write files to fortunately there's a better way to do this using what is known as dependency injection

148:34

let's go back to my service and it's my logger dependency my service it still

148:39

uses the log this method but this time my logger is not explicitly constructed by my service instead my logger is

148:47

passed in as a Constructor parameter my logger is injected into the my service

148:54

Constructor this way my service doesn't need to know how to construct or configure the logger it just receives it

149:01

and can start using it right away but if my service doesn't construct the logger

149:07

who does it well snet core provides the I service provider which is what is

149:13

known as the service container your application can register my logger and

149:18

any other dependencies with I service provider during starup which is typically done in your program.cs file

149:26

then later when a new HTTP request arrives and your web app needs an

149:31

instance of my service the service container will notice its dependencies and it will go ahead and resolve

149:39

construct and inject those dependencies into a new instance of my service via

149:44

its Constructor this enables multiple benefits for your application to start

149:50

with my service won't be affected by changes to its dependencies it doesn't matter how many times the Constructor of

149:56

my logger changes there is no need to change my service moreover my service

150:02

won't be creating instances of my logger so it doesn't need to know how to construct or configure it if your

150:09

application uses minimal apis dependencies can also be injected as parameters to your minimal API endpoints

150:16

finally dependency injection opens the door to using dependency inversion but what is dependency

150:23

inversion the dependence inversion principle states that code should depend on abstractions as opposed to concrete

150:31

implementations let's bring again our my service class and it's my logger dependency currently my service depends

150:39

directly on my loger which allows it to write logs to an output file but let's

150:44

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

150:51

would like my service to start using a new Cloud loger class we could modify my

150:56

service to receive and use a cloud logger instance instead of a my logger instance however what we can do instead

151:04

is modify my service so that it depends on a new ey logger interface instead

151:09

which provides all the required login functionality then we can have both my

151:14

logger and Cloud ER implement this new interface with this we are decoupling my

151:21

service from the logger dependency allowing it to use my logger Cloud logger and any future logger

151:27

implementations without ever having to modify my service the only thing that

151:33

the different loggers need to do is to implement the interface that my service depends on in terms of the code this is

151:40

how you would now inject the logger into my service so the main benefit of of

151:46

using the dependency inversion principle is that dependencies can be swapped out without having to modify the class that

151:53

uses them but also it is now much easier to test my service since the loger

151:58

dependency can easily be mocked out or stopped and finally your code is now

152:04

cleaner easier to modify and easier to reuse now before we start using the bend

152:09

injection in our code there is one more important concept to understand which is the service lifetime

152:16

we now know the basics of dependency injection in ESP core we know that on Star app your application will register

152:23

the dependencies like my logger here and later when an HTTP request arrives I

152:30

service provider will resolve construct and inject an instance of my logger into

152:35

a new instance of your class my service in this example what is not clear is

152:41

what happens when a new request comes in should I service provider create a brand

152:47

new my logger instance for the new request or should it reuse the same instance what if another service that

152:54

also has a dependency on my logger needs to be created in response to a new request sa my logger instance or new my

153:01

logger instance the answer to this lies in the service lifetime which you

153:07

configure when you register my logger with I service provider there are three available service lifetimes so let's

153:14

take a look at each of them let's say that my logger is a very lightweight and

153:19

stateless service so it's okay to create a new instance every single time any

153:25

class needs it in that case you would register my logger with the at transient

153:31

method when the first HTTP request arrives the I service provider as usual

153:37

will resolve construct and inject a new instance of my logger into my service however when a new HTTP request

153:45

arrives I service provider will construct and inject a brand new instance of my logger

153:53

which has nothing to do with the first instance furthermore if there's any

153:58

other service that participates in any of these HTTP requests and also has a

154:03

dependency on my logger it will also receive a brand new instance of it so

154:10

transing lifetime services are created each time they are requested from I service provider

154:16

what if my logger is a class that keeps track of some sort of state that needs to be shared across multiple classes

154:24

that participate in an HTP request in that case you would register my logger

154:29

with the adcode method here when an HTTP request arrives the I service provider

154:36

will again resolve construct and inject a new instance of my logger into my

154:41

service but if there's any other service that participates in that same HTTP

154:47

request and that also has a dependency on my logger it will receive the exact

154:52

same instance of this dependency however if a new HTTP request

154:58

arrives the service container will create and inject a brand new instance of my logger instead totally unrelated

155:05

to the previous instance so esope lifetime services are created once per

155:11

HTTP request and reused within that request finally let's say that my logger

155:17

is not cheap to instantiate and it keeps track of a state that should be shared

155:22

with all classes that requested during the entire lifetime of your application then you would register my

155:29

logger with the at Singleton method as usual when an HTTP request arrives the I

155:36

service provider will resolve construct and inject a new instance of my logger into my service and if there is any

155:43

other service that participates in that same HTP request and that also has a dependency on my logger it will receive

155:50

the exact same instance of this dependency but furthermore if a new HTTP

155:55

request arrives the service container will once again provide the same instance of my logger to any of the

156:02

classes that requested and it will keep doing so until the application is shut

156:07

down so singletone lifetime services are created the first time they are

156:12

requested and reused across the application lifetime now that you understand the benden injection in h net

156:19

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

156:26

context across our API endpoints we just learned about the Bendis injection and service lifetimes

156:34

but how are those related to our DB context well going back to pr. CS let's

156:40

look at this line here line seven builder. services. atsq light with gamore context

156:46

this line is actually registering our DB context gam store context into the service provider which is a service

156:52

container and it is doing so with an scope lifetime so it may not be may not

156:58

be evident here but when you see this line what's really happening under need at some point is something like builder.

157:05

services. add scoped with game store context right and there's of course more

157:12

going on than than just this but this is the key part so gamar context is getting

157:17

registered with the service provider so that later on anywhere in our code base we can go ahead and inject that instance

157:23

of gain store context into our code so that we can take advantage of its services now why why is this gain store

157:31

context registered with a scope Lifetime well by doing a scope lifetime this ensures that a new instance of the D

157:38

context is created and dispos for every single request and this is important for

157:44

a few reasons like for for instance database connections are limited and they are a relatively expensive resource

157:51

so by having the DV context registered as a scov life time that ensures that

157:56

the connections are opened and closed efficiently also DB context is not threat safe so having a single instance

158:04

of the context across multiple requests would lead into concurrency issue so we don't want that we also have to think

158:10

about transactions right so having a separate DB context instance per request

158:16

makes it easier to manage transactions and ensure data consistency across a single unit of work without interference

158:22

from multiple requests and finally reusing the same D context instance

158:27

across multiple request could lead to increased memory usage because the DV context keeps track of changes to

158:33

entities over its lifetime so by having a scope lifetime that ensures that the DV context is short lift and R reducing

158:41

the memory overhead and potentially improving performance all right so now

158:46

that we understand that our gam store context is getting registered as a scope service we can start taking advantage of

158:52

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

158:57

do now is go back into our end points so end points over here games end points

159:05

all right let's collapse this and close that and

159:10

we can now go back into our post empo let's start with post this one over here which is the one

159:17

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

159:24

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

159:31

been registered in the service provider so for that all we have to do is just add gam store context DB context all

159:41

right so at WR time a minut court is going to take care of of resolving and providing us an instance of that context

159:48

right here without us having to do anything else and so from here on we

159:53

don't need to be creating uh these DTS manually as we're doing it here instead

159:59

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

160:05

it's going to be just of type game equals new okay and now I'm going to do

160:11

control do here so we can import our Gam store. api. entity Nam space all right

160:18

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

160:23

the name so name is going to be new game. name and the next one is going to

160:29

be the gener right so we want to assign a gener here now the problem is that if

160:34

we go into new game do we're going to notice that currently the gener that we

160:39

have in this new game in this D and I'm going to do F12 or here on J to see once

160:44

again the definition of our create game dto the problem that we have is that gener is just so far a string but this

160:51

is no longer going to really play well with our scenario because think about it our client is likely not going to send

160:57

us the string corresponding to the generate likely the client will will send us the ID the unique identifier of

161:03

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

161:11

dto at this point so that we can receive the proper ID of the

161:16

let's go ahead and change this right so let's go and do generate ID all right

161:23

and with that let's go back to games endpoints and now we can actually assign

161:28

a gener to the game now what gener will be assigned because this is this is an

161:33

actual entity right so to do that what we're going to do is just say d context

161:38

that gener that find and we're going to say new game. gender ID

161:46

right so with that we are actually taking advantage of the D context to find the instance of generate that

161:52

matches that gener and then we're going to assign that into a generate IND The Entity but also remember that we also

161:58

have a generate ID property in game itself so we should also assign this to

162:04

new game. generated right and then let's just go with the price which is you g

162:10

the price and finally the release date which is new game. relate okay so that

162:19

is the creation of our entity and then we have to go ahead and uh add this

162:25

brand new entity into our DB context and to do that we can do DB context. games the games D set and then

162:33

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

162:40

that Entity framework and the DV context can start keeping track of this brand new entity that will need to be stored

162:45

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

162:52

prefer to use games just to be a bit more explicit to tell where exactly this game entity is going to go lastly what

162:59

you also have to do is just say DB context do save changes right save

163:04

changes is the method that's going to actually transform all of the changes that have

163:10

been tracked by Entity framework so far in this case the addition of the new entity it translates that into whatever

163:15

SQL statements needs to be executed into the database to insert the new record

163:21

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

163:29

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

163:34

ahead and open our terminal I'm going to do the net run

163:40

right let's go into our games at HTTP file let me class this for a moment and

163:48

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

163:54

that as you as you know we are not sending the get gener as a string anymore we are sending the ID right so

164:00

this has to be gener ID now now what id are we going to using here well we have

164:05

to remember what id we're using uh when we create the gener so if we go back

164:11

into Data gain store context remember that here is Will we declare statically

164:17

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

164:25

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

164:32

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

164:40

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

164:46

quickly for Minecraft it's going to be just $1 1999 let's once again right click send a request and the record has

164:54

been created right we can see that Minecraft got created over there uh it

164:59

got assigned ID number one by the database in this case ID number one and

165:04

everything is looking as it should for a brand new Minecraft game okay and of course what we want to do now is verify

165:10

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

165:18

my server for now contrl C to stop the server and let's go back into our SQ

165:23

Explorer let's right click on games and I'm going to say show table okay so if

165:29

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

165:35

created into our sqi database right so that since we working properly okay so

165:41

so that's great uh but there's one thing that is not working as it should and

165:47

perhaps we should notice that much better so let me close AQ light and uh

165:52

yeah we didn't see that but let me go ahead and rerun our server and uh just

165:58

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

166:05

that something changed here right because the response that we were sending back to the client before did

166:12

not include uh this this a composed gener object with an ID and a

166:19

name if you remember before we were returning back here for the response just generate as a string right so by

166:26

doing what we're doing here right now we have changed the contract of the response back to the client and we

166:32

should not do that right we should respect the contract we were using so far we have indeed changed the contract

166:38

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

166:44

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

166:51

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

166:59

now stop our server and let's go back into games end points so really what we

167:04

should do here is instead of return if we returning if you remember we ret return in this game right here which is

167:11

the actual entity we we should really never do we should not return internal entities back to the client we should

167:17

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

167:24

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

167:34

and then we're just going to be filling in the properties so game that ID game

167:39

that name game that in this case generate that name

167:45

game that price and gain that release date now there's a warning here that says that hey this gener property might

167:53

be null so is that okay I mean it's a possible null reference now we know from

167:59

the fact that because we are doing over here up here remember that we are filling it it with the the right value

168:05

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

168:11

key related exception when we try to save the right so if we manage to get to this

168:17

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

168:24

so we're because of that we're going to be using the null forgiving operator so this exclamation mark over there to say

168:31

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

168:36

name property just fine right and with that in place we can now return instead of the game we're going to be returning

168:43

game game dto just like that okay and so

168:48

with that change let's go ahead and rerun our server all right let's go back

168:53

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

169:00

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

169:07

uh send a request and as you can see on the right side uh yep so the game got

169:13

created just fine it got a D3 which makes sense but more importantly if we

169:18

scroll down we're going to notice that the gener now is back to what it was before it's just a simple straight

169:23

that's what we're returning even when the input includes the generate ID as you can see there it's just the generate

169:29

ID but the response is z so that's the way that we can keep that contract with

169:34

the client even when our internal structure has changed right and this is why it is very important to give that

169:40

separation between DTS and the data model uh because the DTs is a contract with the client with which you must keep

169:45

at all times but the internal structure can change at any time and you want to have that flexibility all the time all

169:52

right so let's close this and let's uh stop our server now if we go back into

169:57

our code gam s points one thing that we going to notice is that ER I mean this

170:02

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

170:09

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

170:16

entity to return it back into the client so to simplify things a little bit here

170:22

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

170:28

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

170:34

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

170:40

course a way to deal with this is to be is to use a mapping Library like for instance automapper is a very popular

170:46

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

170:53

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

170:59

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

171:04

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

171:10

fully fledged Library just for this little mapping here I would only start thinking about such a library if the

171:16

scenario is really complex right and if I have tons and tons and tons of properties I need to map and I have

171:21

multiple entities and detos and all that maybe in that case but in this case is is very simple there's no need to

171:27

introduce something like automapper a simple extension method should be good enough so let's go ahead and open up our

171:32

Explorer here let's collapse this let's go into solution Explorer actually so so

171:38

we can go ahead and create a brand new directory uh just under gain store. API

171:43

let's right click new folder and let's name this mapping and in that mapping

171:49

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

171:57

right collapse this let's fix a name space control dot in the namespace Declaration to change Nam space to game

172:03

store. api. mapping now since this class is meant for extension methods once again we make it a static class and

172:11

we're going to create a couple of methods the first one is going to map uh create game dto instance into a game

172:18

entity instance so let's create public static it's going to return game to

172:26

entity okay so this is extending create game BTO new game all right and I guess

172:34

we can just call this one game like that okay so what should we have here so if

172:40

you go back to game end points we want to have something like this right

172:45

this logic over here so I'm going to copy this into game mapping and paste

172:50

that here now let's just scroll down a bit and what we're going to do is just

172:56

say return new game okay and let's fix things a bit here so this is going to be

173:02

just game that name now for the generate we cannot actually access the D context

173:09

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

173:16

care really about the dto okay and then for gener ID we have game that gener ID

173:21

then we have game that price and then we have game. release date all right so

173:27

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

173:34

to help us map a game entity back into a game dto so public static game dto to

173:45

the so we're going to be extending game game entity right there like that now we

173:52

what are we going to return here so going back to game's endpoints we're going to be returning what we do over

173:57

here so let me copy this section down here okay and all we have to do really

174:04

here is just say return new and yeah that's pretty much it that

174:11

will return a brand new game dto so with this new extension methods ready we can

174:17

now go back into games end points and take advantage of them right so let's go back first here where we are creating

174:24

our new game instance so instead of that what we can do is say game game equals

174:32

new game. to entity just like that but uh we still have to account for the for

174:39

the generate entity that needs to be attached into the game so because of that we have to still do game. gener

174:48

equals and that's going to be this line here line 59 we have to copy over there

174:53

right there but the rest we can get rid of now so this can go away and uh one

174:59

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

175:06

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

175:11

this okay instead of sending game Det we're just going to say game. 2D that's

175:18

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

175:26

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

175:32

ahead and create a new game that I'm going to populate over here from my other screen so let me replace this with

175:39

that okay it's going to be the Final Fantasy 14 game we generate ID 2 so let's right click

175:45

let's send a request yep and as we can see on the right side it got created and

175:50

it got assigned the proper generate here this role play right it has the ID so yep the mapping is working as expected

175:58

all right let's close this perhaps let's also close this over there let's get

176:04

back to gain sence with our post and point ready uh let's move on into the

176:10

next Endo which in this case is going to be our get endo get by ID actually so

176:16

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

176:22

is to receive the the context as a brand new parameter in the Lambda right so let's go ahead and add game store

176:30

context it's going to be our DB context right there remember that this is injected via the DI and depend injection

176:38

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

176:47

game entity instead right so for that we're going to use switch this into just

176:53

game and then here we're going to say instead of that DB context dot games.

177:01

find and here would can pass in just that ID like that so that's how you can

177:09

quickly find the entity inside the DB context now keep in mind that this find

177:14

method is going to try to find the the game within the current set of games that are in memory right now already

177:21

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

177:28

ahead and find it in the database if need right so it's a very efficient method now one thing that we need to

177:33

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

177:39

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

177:47

two dto a game dto that's not going to work very well that is because let's

177:52

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

178:00

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

178:08

the generate as a string and that is because the client would likely want to

178:13

have the generate ID to be able to use it in the UI right imagine a UI where

178:19

the user is going to be selecting a generate from some sort of drw down list right and so that draw down list will

178:25

have to match the generate ID that was returned by us but if we just keep returning the string that's going to be

178:31

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

178:37

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

178:42

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

178:48

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

178:53

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

178:59

ahead and open up our Explorer contr shift e let's go into

179:05

DTS and actually to keep things simpler let's go back into our file explor over

179:10

here and let's uh let's just copy game d let's make a copy of this one and just

179:16

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

179:25

that game details dto okay so game details dto let's rename that over here this is and like I said this is not

179:32

going to have a string gener it's going to be an INT gener ID okay so that's

179:38

game detail CTO now since we have we are renaming game detail CTO I mean we are

179:44

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

179:50

is no longer going to be just game dto let's rename this one into game summary

179:55

dto right to to more clearly reflect the fact that this is a summary of the game

180:00

that includes a gener as a string and not an ID okay so this is going to be

180:05

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

180:13

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

180:19

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

180:28

what we should be returning from this method but also we want to here introduce a brand new mapping method to

180:34

return a game detail CTO so let me just copy this method quickly let's scroll

180:39

down and let's paste it down here let's let's change the type here into game

180:46

details dto and this is going to say to game details dto right and here of

180:53

course is going to be we're going to be returning game. generate ID all right

180:59

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

181:07

doing anything else so in this list this list is going to go away soon but for now just to avoid the compilation errors

181:13

let's change this into game game suto then let's scroll down over here

181:20

this is our post method map post so this should return now to game detail C right

181:27

that's what would make most sense to the client right instead of returning that

181:32

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

181:39

and generate in the game d so two game details so yes we are breaking the

181:44

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

181:50

that we're going to be returning that created a game from the poll okay so game details DET now let's keep

181:57

scrolling down let's see what else we have here this should be game sumary dto

182:02

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

182:09

we are going to be returning really only the details right game details dto and

182:16

which if you remember let's go back to game details dto it does not include the generate as an actual object but just

182:22

the gener ID because of that back here we no longer need to assign the gener

182:28

over here with this line here there is no need because entity framew will take care of properly assign the generate

182:34

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

182:40

were really only doing that because we needed that later on for the mapping uh but really is not needed anymore and now

182:47

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

182:53

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

183:00

to return game do to game details D all

183:06

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

183:13

the screen and then do run let's close this let's perhaps close this to DTS and

183:19

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

183:26

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

183:32

by ID I'm going to right click and I'll hit send request and as expected things

183:38

are working properly right so we are getting our 200 okay we are getting our Minecraft game here and notice that we

183:44

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

183:51

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

183:58

to one of the gener that it is displaying on the screen right imagine some sort of drop down so he will use

184:04

this to just select that that gener in that screen right for our user right so

184:10

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

184:18

ID now let's go back into gains end points and I just stopped the server let's Now work on our put operation

184:25

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

184:33

our update game dto so that it can also use a generate ID and not a generate

184:38

stream so let's go back into Explorer let's go into update game dto and we're

184:44

going to be doing the same change that we did for create game d so instead of

184:49

the string here we're going to say int generate ID like that and because of

184:56

that now we have to go into our mapping to also Define some sort of a method to

185:02

do the mapping between that update game dto and the entity so let me go ahead

185:07

and actually copy the very first method let's just copy this and I'm going to just open a space here

185:13

that copy and now we're going to be mapping not create game dto but update

185:20

game dto right into the game instance now one

185:25

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

185:31

the fact that this update game dto does not come with an ID right remember update game dto does not have any ID but

185:38

we do want to create this game with an ID because the user has specified that he wants wants to replace a very

185:44

specific entity with a specified ID so because of that what we can do is just to add one more parameter here that's

185:51

going to be int ID and then we'll use that ID as the ID of our return game

185:59

entity so let's assign it over here ID equals ID okay now how do we use these

186:06

two entity method back in our endpoint so let's go back into games endpoints

186:12

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

186:18

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

186:25

is the following let's do bar existing game is going to be DB context and of

186:32

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

186:40

context DB DB context right we have now injected that into our

186:47

maput and we can take advantage of it right so DB context dot games. find and

186:54

then it's going to receive that ID okay so now we we are finding the existing

187:00

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

187:06

of this comparison is that we can say if a existing game is null then we going to

187:13

again just return not found so that that stays okay uh but then we got into the

187:19

interesting part right so how do we actually perform the updates well we have to do a couple of things first I

187:24

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

187:31

entry inside our DB context and replace it with a brand new entity that we are

187:38

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

187:45

method that you can use to locate the current entity inside that DB context

187:50

right so for this one what we can do is just say existing game right and for

187:56

inside that we we can say current values right so that pulls out the current values of that entity and then right

188:04

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

188:10

all of the values of the old entity so here we're going to bring in our updated

188:16

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

188:23

the brand new extension method that we use two entity and passing in that ID

188:28

okay and that is how with this just one line we can go ahead and replace the

188:34

existing entity with a brand new entity that comes from the dto right and lastly

188:39

last thing we want to do here is to always do D context do save changes to

188:44

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

188:50

so make sure that this is working so let's go ahead and run our

188:55

server okay I'm going to collapse this back toide HTTP so which game we are we

189:01

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

189:08

we cannot use this this still looking from the list so let's actually let's take a quick look uh pick into the

189:13

database to see what we have so far so Esq Explorer right click on games show

189:18

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

189:24

say we're going to update our stct Fighter game here which has ID number three safe Fighter 2 with ID number

189:31

three so let's close this let's close that and we're going to go down here

189:38

okay I think we have most of it but we don't have the the name so let me actually complete this very quickly

189:44

with something that I have in my other screen over here and what we're really changing here is that Street Fighter 2

189:50

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

189:55

price has changed so game was number three so let's switch it to number three

190:02

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

190:08

because we forgot one small thing which is the gener right so gener should not be like that it should be generate ID

190:16

and the ID of the generate 4 Street Fighter should should be one over there and let's right click and send a request

190:22

there you go so we got the expected 204 no content meaning that this was a success so and to confirm of course we

190:29

can go ahead and use Query for game number three by using our get by ID request over here right click Send

190:36

request and as we can see indeed we are now using c52 turbo and and the price

190:43

has changed so the update operation is working as expect awesome so now let's just close this and let's stop our

190:50

server all right and let's go back into games end points because now it is time

190:55

to change our and get all operation right so so we can actually start

191:00

quitting for all of the available games so let's go all the way up here into our

191:06

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

191:12

longer want to use the games list but uh first thing that we have to do as usual is receive our game store context

191:20

instance here D context okay and then let me send this to the next line to see what we want to

191:25

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

191:33

from those games we want to transform each of those game instances into the corresponding game summary dtos right so

191:41

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

191:50

each game in this Games Collection we're going to say game dot to game summary

191:58

dto just like that and well technically that's all we need to return our list of

192:05

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

192:10

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

192:18

we are going to need the generate property right here right to pull out the name of the gener and um the way it

192:26

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

192:32

attached generat right so gener is going to come empty here so we have to do something to also include the attach

192:39

generate property for every single game and that is if we just open up a brand

192:45

new line here is this include method so include where we're going to say okay so

192:50

for each game make sure that we bring in game.get right if you don't do this then

192:57

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

193:03

to do the proper mapping into two game summary dto to attach the general name into the dto right so that's very

193:09

important in this case and the next thing we also want to do here is a bit of an optimization right because by

193:16

default Entity framework is going to keep track of every single entity that we're pulling out of here is going to do

193:22

change tracking for every entity and if you have many that's really wasted resources right we don't need to keep

193:28

track of anything here because we're just going to return that back into the client right away just one operation so

193:33

we're not going to be performing any updates into the return entities and because of that one of one very good

193:39

optimization I should always do in these cases is just to say say as no tracking

193:45

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

193:51

send them back into the client in this case as is right so that's going to improve the oper the performance of your

193:57

operation over there okay and so yeah that's all we have to do for the get

194:03

endpoint so let's test this quickly let's do theet run all right let's go

194:08

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

194:15

you can see on the right side now we are getting the actual gains from the database this case yeah we do have

194:21

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

194:29

games declared into the database right now okay so that is working properly and

194:35

notice that for each game we are returning the generate string and not the generate ID which is what what the

194:41

client would expect to display a summary view of all of the available right and so one more thing to

194:47

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

194:54

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

195:00

operation which is actually the simplest to implement so as with all the of the

195:05

other endpoints first thing to do is to introduce our game store context via

195:10

dependency injection DV context and then we have to change the way that we perform our removal of the entity so

195:18

how will we do this so couple of ways to do it but the most efficient way is to

195:24

do the following we're going to say d context. games. where and this where is

195:30

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

195:38

game where game. ID equals ID so that selects the game that we want to

195:45

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

195:52

use to execute delete all right so this syntax here to perform the delete is is

195:58

is known as batch delete and it is a very efficient operation because we don't have to first find the entity just

196:05

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

196:10

so this one line here one shot is going to go straight into the database find the entity and delete it right away so

196:16

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

196:24

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

196:32

remember if we right click at the very first request here we do have four games right so since we have this one

196:39

duplicated so we have Minecraft two times here let's see if we can go ahead and and uh remove the second entry of

196:45

micr ID number two right so let's close that let's go down here at the very end

196:51

and yeah our delete operation is actually looking at game number two so let's ask it to remove game number two

196:56

so let's right click let's do send request and it seems like was a success

197:02

204 no content means that it succeeded so if you go back into our list full

197:07

list of games right click here send request and let's see what happened so we have ID number one but we no longer

197:14

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

197:22

just close this and then uh stop our server now one more thing to do here before moving to the next topic is that

197:29

well we finally no longer need any in memory list of games right so finally we

197:34

can go back here and we can get rid of this entire uh list of games so let's go

197:39

ahead and select all of this and we can get rid of it so now it is gone okay so

197:46

with that we have completely moved into a res API that is ready to interact with

197:52

the database both for quering entities and also to create update or delete all

197:58

of these entities so that is working properly but there is one more concept that we need to also learn and apply

198:04

into a race API and that concept is the asynchronous pring mode so let's switch

198:10

a slides so we can learn more about today a synchronous programming model and why it is so

198:15

important to understand a synchronous programming let's go through a common scenario you might be familiar with

198:21

which is making breakfast let's say you start by heating your pan for a few

198:27

minutes and then when ready you fry some eggs there we would also like to have

198:34

some bread for a breakfast so after your eggs are ready we bring up the toaster

198:39

and toast our bread then then when the bread is ready we add some jam on peanut

198:46

butter on it finally our breakfast would not be complete without some juice so

198:52

let's pour in some orange juice in total it took us about 30 minutes to complete

198:57

our breakfast but is that really how you would go about preparing your breakfast

199:04

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

199:11

hitting your pan and while that happens you will also start toasting your bread and while

199:18

those two things happen perhaps you can also pour your orange juice eventually

199:24

when the pan is ready you go back to it and fry some eggs and once the bread is

199:30

toasted you go and put the jam or peanut butter on it doing things this way you

199:37

can be done in much less time say 15 minutes and perhaps you can can spend the rest of the time enjoying your

199:44

breakfast when comparing these two ways going about making your breakfast we say that the first approach is synchronous

199:52

since you won't start a new task until the previous one is complete however the

199:58

second approach is asynchronous since you don't wait for a task to be complete before starting your

200:04

next task instead you start as many tasks as you can and eventually you turn

200:11

your attention two tasks that are ready for you so you can continue with the next task in a similar way you can

200:19

perform a synchronous programming in your hnet Cod applications when a client sends a

200:24

request to the web server you want to start handing the request in your endpoint in an asynchronous way so that

200:32

your cook the Krell web server is immediately free to start handing the next request so as your endpoint starts

200:40

an asynchronous call perhaps to your DB context and the DB context in turn

200:46

requests data asynchronously from the database the web server has also started serving the next request also

200:53

asynchronously when the database eventually Returns the requested data the DB context will resume work and send

200:59

the data back to the endpoint which in turns with Source work transform

201:05

entities into dtos and sends the data back to the web server who in turn responds to the original client request

201:13

after this the application continues starting order tasks asynchronously and

201:18

resumes work whenever necessary as you can see the asynchronous programming

201:23

model brings in multiple benefits your application gets improved performance

201:30

since you avoid blocking colors and free them up to perform other tasks which

201:36

also results in overall better responsiveness you are able to escale your application better because it can

201:43

handle more requests and users simultaneously without getting bed down by waiting for Io operations to complete

201:51

and also the use of task objects in combination with async and await keywords provide a simple and intuitive

201:58

way of writing asynchronous code as opposed to having to deal with threads and callbacks directly now that you

202:04

understand the asynchronous ramming model and its benefits let's see how to put it to work in our current res API

202:12

taking advantage of the asynchronous Ring model in our net vers API is

202:17

actually very straightforward so here we're back in a games endpoints right and so we're going to see how to

202:24

introduce this autel model in each of our endpoints and let's start with our H

202:29

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

202:37

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

202:44

return the games but instead of that it is going to return a task that can be awaited until the operation actually

202:51

completes that way a minut core does not have to block on the operation until it is done right so anything that goes out

202:58

of your process like going into the database going to the file system going to the network all of those operations

203:04

we want them to return just a task that can be waited and that can be resumed later on when the operation completes so

203:10

in this case really all we have to do is just to add one more call at the end here to

203:16

transform the output games into a a list in an asynchronous way so we're going to

203:22

say to list async right and so that's going to now

203:28

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

203:35

this returns not just a list but it is a task of list right so because of that

203:42

the wrong time can wait for that task and it's going to resume when the games actually come back from the database all

203:49

right and you're going to notice this convention where you use the Asing suffix this suffix over here for every

203:56

operation that is going to return not the actual object but just a a task that

204:02

includes the result of the operation right so many libraries you're going to notice that they use this convention so

204:07

prefer these asynchronous methods when you invoke these kind of apis right and you should also be using this

204:13

same convention if you write your own asynchronous methods right so that works

204:18

but the other thing that you also want to do is to use the async await combination of keywords for your own

204:25

method now in this specific method here it may not be absolutely necessary because it's just a one liner here so

204:32

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

204:38

understand let's go ahead and add async and a weight here right so we're clearly

204:46

signaling the compiler that it wants to execute this as an asynchronous operation and that it needs to await for

204:53

the task here to complete before returning the data back into the client

204:59

now we can follow this same convention across all of our methods to make sure that all of the operations work in an

205:04

asynchronous way okay so let's go down into map get to get a Again by ID and

205:11

just like with in the previous method we're going to now transform this into an async right so now it's an

205:17

asynchronous operation and we need to await every single operation that goes outside of our process right in this

205:22

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

205:30

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

205:36

into find a sync just like that right so now just like in the previous method

205:42

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

205:47

retrieved from the database let's move on into our post method now which once

205:53

again is going to be an asynchronous operation and then what is going to be the actual operation that we need to

205:58

wait for that's going to be our save changes so this is the only operation that's actually going to go outside of

206:03

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

206:10

changes AC okay now let's keep going down into our put operation which we're also going to

206:17

turn it into an async operation like this and here we have a couple of

206:23

asynchronous operations the first one is going to be the one here to find the game this one in line 53 so this we

206:29

should await await and then find a sync right so now we can find it in a

206:35

synchronous way and then we go all the way down into save changes and again we

206:41

want to do await save changes async

206:46

finally let's go down into our delete operation which again we're going to make it a sync and then the the

206:54

operation that we want to wait here is to is to is the execute delete over here so remember that this goes straight into

207:01

the database to perform the deletion so we're going to say await and then execute delete a sync all right and well

207:10

that really takes care of all of our API endpoints now everything going on in this endpoints H class is really

207:17

asynchronous but there's one more location where we should also take advantage of the synchronous grabing

207:23

model and that is the location where we perform the migration when we start application so where is that happening

207:29

let's go back to Explorer let's collapse this and let's go

207:34

into go up data extensions under our data directory data extensions so

207:41

remember that this is the place where we eventually go ahead and just execute any pending migrations when the application

207:48

starts so this should also work in an asynchronous way right because it has to go out and talk to the database and that

207:54

could take time so what we're going to do is change this operation in a few

208:00

ways the first thing is that since we're going to be returning uh no longer just

208:05

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

208:11

task so that whoever calls this operation can actually await on that task now we also need to follow the

208:18

async and a weight convention right because that simplifies the way that we can deal with this task and then instead

208:25

of calling migrate we want to call migrate async okay and now our method is really

208:30

an asynchronous me but remember that I mentioned that anytime you deal with asynchronous operation you should name

208:37

your methods with an async suix so that's a convention across the entire net and C ecosystem so just like myig

208:44

async uses the async suffix over there you want to also modify your myig gr DB

208:49

method here so that it's name my grade DB a sync right just like a as a

208:55

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

209:03

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

209:12

here so this warning is alerting US of the fact that this method is asynchronous right because it Returns

209:18

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

209:24

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

209:30

properly wait for the task to complete before moving on to the next thing all right and so yeah that's pretty much all

209:36

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

209:42

that everything is working properly including this this last change is to well let's go ahead and delete the

209:48

database and let's see if when we run the application it can actually recreate a database and then we're going to start

209:54

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

210:01

make sure also that yeah the server is not running right now so let's right click and delete our game store database

210:07

so delete okay the database is gone so it has to be recreated when we restart the

210:14

application so let's go ahead and open our terminal okay let's collapse this do

210:20

and run let see what happens all right apparently everything went properly the

210:25

migrations were applied as you can see here migration got applied we should be able to see the database back here so

210:32

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

210:39

post operation here to verify that things are working properly so I'm going to right click here send request yep the

210:46

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

210:53

click here send request yep we can query for games so things seem to be working

210:59

just just fine and now we're taking advantage of theing Prim model which makes things much more efficient for our

211:06

net R API right so let's go ahead and close this and let's stop our server

211:11

all right and get back to games endpoints that's CS at this point our games endpoints are complete and what i'

211:19

like to do now is to show you how these endpoints can be integrated into a modern web client but before we can do

211:26

that there's still one missing piece and that piece is our generous Endo because

211:31

we have the ability to fully interact with games right now but we don't have that ability with the genders and it's

211:38

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

211:44

those generes because we have some UI elements in the client that are going to need to query for those gener so let's

211:51

go ahead and apply everything we learned so far about net apis to see how quickly

211:57

we can come up with a brand new endpoint to be able to query for those Jers so

212:03

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

212:09

we're going to need is a brand new dto which is going to be the dto that

212:14

represents the generous so let's head back into solution Explorer and let's go ahead and right

212:21

click on DTS new file remember that this is a record type and let's name this one

212:26

generate dto all right let's collapse this let's go ahead and fix our namespace install that api. dtos so

212:34

pully record class generate dto let's use the simpler syntax here to specify

212:40

an ID and a name all right so now we

212:45

have the dto let's go ahead and Define a proper mapping for Transforming Our

212:52

gener entity into gener dtos so let's go

212:57

into the mapping directory and let's actually spin up a brand new mapping class because this is going to be for

213:03

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

213:10

and let's name it y mapping okay let's collapse this let's

213:15

fix a name space it's going to be G start. api. mapping and then this is

213:21

going to be a static class because it is for extension methods let's define just one method public static gener dto to

213:30

dto and then we're going to be extending the gener class which is already defined in our data model so gener and what

213:39

we're going to do here is just to return a new Genero with generate. ID and gener do

213:49

name all right so the mapping is ready and then the next step is to Well define

213:55

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

214:02

endpoint directory let's go ahead and and create a brand new endpoints class

214:08

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

214:15

generous endpoints all right so here let's go ahead and also fix an name space gam

214:22

store. api. end points it's going to be a static class and let's follow the same

214:28

idea as the previous endpoints class so it's going to be a public static and we're going to be returning a route

214:36

group Builder right because we're going to be using route groups here let's let's name it map generes and points and

214:45

then let's extend our web application class app right so remember that we can

214:52

first create this map group this way so bar group equals app. map group so our

215:01

group is going to go into generous right generous and then uh

215:07

let's go ahead and Define just one one endpoint so group.

215:13

maret okay so this is going to be go just under generate so we'll just put that forward slash over there and then

215:20

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

215:27

sync and then for the parameter for the lamb we're going to be receiving our

215:33

game store context once again install context DB context and then we have to

215:39

specify something something to do with this with this Handler right right so let's go to the

215:45

next line let's close this and here what we're going to do is just say await okay

215:51

so how do we retrieve all those gener well we use a DB context so DB context

215:56

dot generous right now if you remember here's where we have to project the

216:03

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

216:11

okay so for each gener we're going to do generate. Toto all right and then remember we also

216:20

said that um for this kind of operation that does not need any tracking for an

216:25

Entity framework then we just want to send back the genders directly to the client we're going to say that as no

216:31

tracking and lastly we want to make sure that this returns an async I mean returns a task as part of an Asing

216:37

operation so we're going to do two list async okay and let's actually send this

216:43

to the next line like that all right so that defines our end point and last

216:48

thing to do here is just to return our group awesome so yeah so the endpoint is

216:55

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

217:02

to just close solution Explorer let's go back to file explorer and I'm going to open up my

217:07

pram CS file over here and just under map games end points I can insert a

217:14

brand new line and let's just say app. map generous endpoints like that all

217:21

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

217:29

we're going to need here is perhaps a new HTTP file so that we can add our new

217:35

request for J right so let me collapse this because we do have this gamat http but since this is different so let's

217:42

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

217:48

one generous. HTTP there and all we're going to do is just say here get and

217:56

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

218:04

other file there and then the pad is going to be under generate right all

218:10

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

218:16

you can see on the right side this was a success 200 okay and we can see down

218:22

here that we are properly returning all of our game genders so just like that we

218:28

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

218:36

go ahead and close this and let's stop our server and and with that we're ready

218:41

to go to the last part of our tutorial which is where we're going to integrate this netr API with an actual client

218:50

application now this is totally optional because we have already done all of the backend work here and that's what we

218:55

wanted to aieve but I also like to always see how this actually serves the purpose of some client because there's

219:02

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

219:08

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

219:13

client in this other vs code instance over here I named it gam store. front end this is a very simple blur

219:20

application with serers side rendering so nothing fancy really and I'm not going to go over the code of this H

219:26

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

219:33

can see the process from scratch how do I I created this little front end here is very simple really uh but um really

219:40

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

219:46

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

219:53

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

220:01

I'm going to copy that and let's head back into our front end and I'm going to

220:06

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

220:14

go back into our back end and let's just do run so the back end starts it's ready

220:21

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

220:27

it run all right so it is up and running and I'm going to go ahead and click and

220:32

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

220:38

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

220:45

right now in our back end okay so not much going on here all is this is is

220:51

render rendering a simple table with the list of games and for each game you can see that we have uh butons for editing

220:58

the game deleting the game and there's also a Buton over here for creating a Rand so let's actually go ahead and

221:04

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

221:11

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

221:18

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

221:27

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

221:34

ring awesome game so it's going to be role playing the price is going to be

221:39

$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

221:47

ahead and click on the save button and as you can see it went ahead and stored

221:53

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

222:00

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

222:07

can see that the brand new game got created over here here right so this is really talking to back to our receip

222:13

okay and so let's see how what we can do about an update operation perhaps right

222:18

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

222:25

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

222:33

save and as you can see it did save it properly without any any problems all

222:40

right awesome and then uh yeah before we try the delete let's actually come up with something something that we can

222:46

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

222:51

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

222:59

you have a res API that can fully integrate with a modern client like this one and I hope you enjoyed creating this

223:06

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

223:12

that but at this point thanks for watching and I'll see you in the next video

No comments:

Post a Comment