NestJS Beginners Guide - Part 1: Core Concepts and REST API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello my friends welcome to the first video in this nestjs series in this video we will discuss Core Concepts inside nestjs and we will build a restful API together and we will learn a lot along the way I'm so excited so enough talking and let's get [Music] started this channel is 100% supported by independent individuals like you so if you want to support me and support my content and my work consider going to the link Down Below in the description box where can buy me a pizza or two so let's get started in njs first of all what is nestjs njs is a nodejs framework while no GS is a very minim minimalistic uh runtime that lets the users to pick and choose the kind of tools they they need for uh their applications uh like handing requests and API responses and middlewares and web sockets and how to do their the file structure and so on njs is a framework that um takes care of all of that so that we as Developers can think of or spend our time on actually building applications instead of um doing some configurations so an sjs creates an outof thee boox solution an outof thee boox application that is scalable and losely coupled and also testable and maintainable now what is Loosely coupled and what is maintainable and testable we will talk about that when we talk about something called dependency injection also njs is a framework that will not lock you inside some specific implementation of nodejs like Express or fastify because you can plug in any any solution or any nodejs solution that you feel comfortable with by default it works with expressjs but you can uh plug in festify like it is mentioned inside the documentations so and also another thing about another great thing about njs is that you you not only build HTTP uh Solutions like expressjs but also you can build um like restful apis graphql apis microservices websockets anything you want even CIS you can build CIS with njs and um njs uses something called dependency injection as I told you before um this dependency injection system makes um our classes or our files easy easily testable and maintainable and I will show you later how to do that okay so the first step in learning nestjs is actually to install something called the CLI so njs has a official CLI and in order to install that we go to npm install I want to install it as a global dependency and then I will write at nestjs CLI now I already installed the CLI but for you you might not install it before so uh give it a shot and wait for it until it's completes it completes so once the CLI completes installing you need to make sure that it is installed and to do that we go to Nest D- version and it should give me some number in my case 10.4.2 because it's the latest version so far okay now in order to create n SGS application we go to Nest new and click enter and here it will it will prompt me with the name of the application and my case I already created a folder if you can see here I already created a folder called Pizzeria so U because I want want to create a pizzeria folder Pizzeria application so I want to click on um dot in order to create the application inside this folder and click on enter and then npm so the idea of our application how we want to build it is that we want to build an an app where we have uh where we where the users like sign in users or signed up users uh can actually get access to pizzas and maybe remove pizzas or create new pizza or create new item let's suppose it's uh it's a restaurant where you can add content but of course we don't need everyone to add so we will limit the the ability for users to add or modify our resources to only logged in users and probably admins so we will see how um in the future how we will Implement authentication and authorization where we build uh roles and um like admin role or like sign in user role and also build authentication because we don't need everyone to get access to our resources and our amazing Pizzeria items so yeah let's wait for this application to be installed it should be done in a minute or two I'm waiting okay as you can see it's um complete and now if I see here I see all the files and the folders that the nli created for me and the first step I usually make is when I'm working with nestjs specifically since it's already in n in typescript and also on top of that it uses es link as a linta so I usually go to the es linter um configurations and usually comment it out so that I don't get bothered by all the rules that are applied um inside our code base because typescript is already annoying and we have es L on on top of that I think that's too much at least for me if you think that's a nor you can keep it but for me I want to comment it out so let's see what is inside our application we have the source folder okay we have the source folder this is the source folder this is the um bulk of our application where we will build um everything inside in here this Source folder and inside here you can see a file called main TS main TS is the entry point of our application which means that if we want to do any root level work like connecting to a database and you will see later how we can create a global validation uh we do that inside this file because it's the root level it's the first file that uh njs reads in order to create the application uh and inside here you can see the nest Factory that creates the uh application for us using something called module app module we will talk about that later and then uses this app in order to listen on Port 3000 and uh yeah so let's let's uh start our application in development mode if I go to package.json you see I have this uh script start do start Dev so I want to run npm run start Dev in order to start our application in development mode and in watch mode actually okay so I want to close this and this and go back to Mains okay from MTS I told you about app modules so let's open app modules see what's inside in here inside the app module we have something called the class because njs uses class classes heavily and on top of that we have a here something called a decorator and decorators are just ways to add metadata to um to classes to functions and so on so in this case this metadata adds some U uh this sorry this decorator adds some metadata to this class and usually it has for um the the module the module class it has um four properties that we can add to the class and here the left one is exports okay we don't need to add all of them since exports is an empty array or Imports an empty array we don't need to add any of that but uh it comes by default with controllers and providers so what is a controller and what is a provider um we we will talk about services or providers they are the same thing we'll talk about them in the next video but for now I want you to understand a concept very import important concept which is when you go to controller okay and the controller um the controller is responsible for handling incoming requests and also outcoming responses so it's the interface that uh is responsible for talking back and forth between the user and the API okay uh for example here get hello or let's say get pizzas okay if I want to um create this function where the user can get all the pizzas in our application I defined a function here that runs whenever the request hits this endpoint and then I will use the service okay use the service the service actually has implementations like this function this implementation talks to the database to retrieve all the information required for our um endpoint to run uh fine right so for example if I want to get all the pizzas the logic on how to talk to database how to transform the data coming from the database to a shape that the user wants to see okay all this logic goes inside something called a service okay if I want to go here this is the service the service is the last layer that deals with the database but the controller is the layer that talks to the service and it is responsible I mean the controller is only responsible for incoming requests and outcoming responses so this is very important concept to understand and what is a service how to build one we will talk about that later and about controller we will talk about them today okay so this is the idea of service and module and controller and the idea of module in the first place is that we want to uh create our application in a way that all the logic all the features and everything related to our features is encapsulated in its own module okay um I will show you later when we want to build pizzas for example all the logically Rel related to pizzas like getting pizzas updating pizzas creating and uh updating whatever all this logic should live in a separate module and this module called piz's module and if you want to talk about authentication and users and how to sign up user how to sign in user and log out a user we build all that logic inside different module called users module and usually we have the app module the app module is the uh root level module is the main module and if you remember I go to main TS this is the main module that Nest Factory uses in order to bootstrap our application or start or in initiate our application so usually what we have is the app module is the base and the app module is connected to um all kind of modules like pizzas and users or whatever and um yeah and we implement the specific Logic for each module in its uh separately we don't combine things together we can Import and Export logic but usually we uh we isolate all the logic in its own module so let's see how how to do that if I go to a new terminal here and write nest generate module and click enter now NJ CLI will pront me with the name of the module I want to name my module pizzas because I'm creating logic uh specific for dealing with the pizzas or the database so I click enter and you see here that a new folder called pzas was created and inside it I have a new file pizzas. module. TS also was created for me and you see here it's a class and this is a module there is something interesting that also happened since we are using the CLI which is if I go to the app module as you remember the app module is the base module where all modules are connected so in the app module I have uh the Imports the Imports array automatically nestjs Imports the pzas module inside this app module which means that the app module is connected to the pzas module and um we can move from there so now I want to create a controller inside the pizzas module to do that I want to run Nest generate controller and I want to give it a name the name is as usual pizzas we name it the same name as the module so that njs puts this controller inside the same folder and I click on enter and you can see that the controller was created it also creates um this um testing file I don't need the testing file but I can show you different way in order to create a controller without a testing file so to do that I go to the terminal and run Nest generate controller and then I can add a flag which is no spec no spec flag means do not add any testing file related to this controller I give it the name pzas and it should be fine so you see here the pzas controller is created and if I check inside the pzas module I see that also inside the controller array I have the pzas controller was added automatically by nestjs CLI which which also which is also why it is important to create all these files like modules and controllers and stuff inside the CLI instead of just creating files and uh creating class yourself so that you don't bother Yourself by connecting the dots and control connecting the controller with its own module and connected module with the base app module and so on so U you should always use the CLI for uh creating your your resources so anyway I want to clear the terminal and it's time to check inside the controller and play around here and um create our endpoints the first endpoint that we want to create is the get endpoint which comes from the nestjs common module and I want to create a function called get all pizzas because I want this um this endpoint to be responsible for returning all the pizzas inside our database now we don't have a database right now but we will Implement database in uh the next video because it's uh it's its own topic and it requires its own time to create and plug in the database with the NJ s application uh for now we don't need with database I just want to return a string which is all pizzas okay and also Let's test that inside Postman if I go to postman here get all pizzas and click on send you see that I got the response back all pizzas but if you if you look carefully I added a route here which is uh pizza's route to to the um base URL which is Local Host 3000 so I added this pizzas route where this what does this come from it comes from the controller because I I said that this controller uh this controller class all the routes inside this class are under the pizzas route so anything I add here must start with pzas I can show you for example if I add here all and if I try to access this uh route I no longer can access it using just pizzas because the base route does not correspond with anything I have to add slash all and then click Send and now I see all pizzas okay but I don't need this all string so I want to remove it and let's try as we are creating a restful API I want to create uh an endo where I can get a specific pizza with a specific ID because um when we save our items or our pizzas or products whatever they are inside our databases they are assigned some IDs so I want to get a specific pizza with a specific ID and I do that by using a dynamic route like in this case by adding a column and then uh ID or whatever uh parameter name that we want to use so get ID and then here I want to define a function which is get one pizza because I want to get only one and then it's a function that return a string pizza with ID colon and I can use this in order to pass a a variable here now we don't have the variable for ID so let's define that uh inside the G one pizza function here or the route hander it's called r route hander or the function uh I want to define a parameter a decorator which is also uh imported from nestjs common and inside this parameter I want to give it a name which is params and this params is actually an object and this object has ID why ID because I called it ID I can change this to another name and then I have to change this to the same name anyway it's called ID for now so ID its type is string and I can actually D structure the ID as Pizza ID like this case equals prams and I add semicolon and then I use the pizza ID here and now it should work fine if I go to postman let's see so get one pizza I'm getting pizza number 12 if I click Send I set pizza with ID number 12 if I set pizza with ID 15 I get pizza with ID 15 so it's working as expected okay now let's see how we can create another route hander which is uh post the post route Handler is used when we want to create create um a resource inside our database uh in in our case we are creating Pizzeria so we want to create a pizza so post and then I want to define a function called create pizza and inside here I want to add body okay the body is also a decorator comes from the same package wait okay so it comes from the same package which is uh um nestjs common and I want to name the body body and its type is for now it's any but later I will change that to a different type and since it's a function I need to return something which is let's return the body so that whatever the user sends in the request I will return back as a response um yeah let's see if I go to postman and create new pizza and create new pizza I have this um Json object name price um this should be Margarita like this and then price is 45 or let's say 10 whatever it is size small toppings cheese let's click on send and it's send correctly and as you see the response is the same uh as the uh incoming request because we are return the same body okay now let's see how we can uh update but for update we use a method or HTTP method called patch so I want to import patch from the same module it is called njs common and I want to define a function as usual update pizza and inside update pizza I want to update a specific a specific Pizza which is I have to Define an ID and to Define ID I have to add here a dynamic route don't forget that because it will throw an error so update Pizza um here I want to define a parameter the parameter is called params and its type is an object of ID string like in this case string yes and then at the same time I receive not only a parameter but also a body so I want to receive the body object like this case and the body is called body and its type is for now it's any as I told you we will have a more accurate type in the future I mean in in this video not in in a different uh video in this series so anyway the body and then here let's return also the body as the same case of course I'm not I'm implementing any logic regarding updating or creating because I don't have a database but in the next video when we Implement database we will redefine the structure here and we will see how we can add logic to actually create resource like create a pizza or update Pizza anyway um this is body and return return the same body if I go to a patch request like here if you see it's a patch request and I want to send it to Pizza SL1 and I want to update the name okay so click on send you see it's pizza margarita um there is another type of pizza that I like it's Turkish called Kebab so yeah you see whatever I send in the request is the same as in the response okay now let's see finally how we can delete a specific uh Pizza which is also should be intuitive by now the same logic I want to Define delete um decorator and also add the ID Dynamic route and inside here I want to define a function called delete Pizza and I want to accept a parameter called params params which is ID of type string okay now I want to delete or to return yeah let's return the same um or return a deleting pizza with ID of I wanted to to also this structure like in this case before so I want to copy paste yeah everything is working fine now if I go to postman delete let's copy paste here I want to define a route a dynamic route sorry which is I want to delete pizza number one and click Send and you see deleting pizza with ID number one so everything is working as expected now let's see other um other code Concepts inside nestjs and how we can Implement them in our current application so I want you to first we have the any keyword here I don't want any inside our application so let's work on changing that uh the type that we want to create here is something called a dto uh let's go to an empty terminal I run Nest generate I want to generate a class just just an empty class nothing fancy about this class like module or controller it's not specific it's just generic class and I want to give it a name but also I can Define where this class will be created so I want it to be created inside the pizzas route uh and inside the folder gold dto I will explain that now and yeah click on now I want to give it a name which is pizzas do dto and click on enter so you can see that inside this pzas folder I created dto called um yeah piz dto for some reason it it also created a fer called pizzas dto I don't need that um so I want to remove the folder okay so this is the pizzas dto if you see it's just a simple class and inside this class I can Define um properties so what is dto and what is the uh the purpose of a dto a dto is um let's here write it above so you can remember it dto equals to data transfer object so dto is a data transfer object and the purpose of a dto is to define the shape of incoming requests and outcoming responses so the incoming requests we have are in our case here in the controller okay in the controller if I go to for example the create Pizza the body body is the incoming request and I need to Define if specific ific shape to that to that body like price name size of the pizza okay so let's define that inside our dto here I want to create um name which is a string also price which is a number and also size size should be an enum uh the idea of enum in typescript is um enams are specific strings or specific values that we want to create so if I want my size to be small large or medium um if I if I Define it as a string now string can be anything string is a generic um idea okay it's a generic form of of of strings I can write anything I can write my name as as a size but of course my name is not the size of of pizza so I need to define something called an enum so um let's create an enum in typescript let's give it a name pizzas or pizza enum or size enum or I think the better name is pizza size I know defining names for um for our variables inside the computer size is the hardest thing as they say so it's fine now I want to create an enum called Pizza size and inside this enum I want to Define some values which is small which must be a string of small like this and also medium which must be a string called medium or I can Define it as um large which is large like this okay now it's working fine I think I want to export yeah it's already exported and this dto should be the type inside our controller right so let's change that to create okay here I want to rename the name of the dto I call it pizzas dto but it's a very generic name so I want to call it create pizzas dto like this and here create Pizza D now I think it's working fine if I go to the controller inside this controller I want to change the type of body to this dto okay and yeah everything is as expected now if I go to postman if I go to create pizza I should see the uh this the same the same values that I I send must be the same values that I got in the response but what if I decided to change the price from to from number to a string like hello okay of course hello is um is not a valid price but there is nothing inside our code base that says that this is wrong this is an error price must be a number not a string so that's the value of adding dto because we can install a package called npm I class validator okay I should wait a little bit until it's installed and when I install this class validator I can go to the dto and Define some uh decorators like is string okay for the name value and here is number or probably is integer if I want to make it integer but in my case it's a number and here I want to say is enum and the en as you can see the enum uh expects uh gives me an error when I open the parenthesis which means uh it expects some values let's go back if I okay so anyway if I go here inside the enum declaration file you can see that I I must pass a value called entity and um validation options are just optional but I must provide an entity okay so I have to provide here an entity called Pizza size in order to let this um this decorator know what enam I'm working with so yeah it's expected and now if I go back to here and try to send okay there is nothing preventing the uh the API from uh nothing preventing the user from sending a string inside the price right although I added these validators or these validation rules and the reason is because tjs application is not aware of the validation that I created these are just decorators I have to add something to our root um to our root application in order to let it know that hey hey SGS application I want you to validate any incoming request so to do that I go to main TS because remember uh in main TS is where we do the uh root level work for our application here after creating the application I can Define AB do um I forgot the name I think it's valid uh Global yeah set global oh no let me check on my notes Global yeah use Global and you can see here I have Global filters Global guards Global interceptors and global global pipes and uh what I want is global pipes okay and inside the global pipes I want to define something called a validation pipe validation pipe okay and since we Define the validation pipe as a global pipe this means that any incoming request will be um validated by this pipe and if I go to postman and send the request okay I think something is broken here class Transformer package is missing so I have to install this class Transformer the reason is because class validator depends on class Transformer so I have to install it clear npm install class Transformer um let's see if I refresh okay now it should work fine if I send yeah if I send the request you see the price is a string and I get an error saying price must be a number conforming to the specified constraints and also if I try to change the size to something like hey and here I change it to eight and click on send you see also an error message saying size must be one of the following values small as medium and large and how was the how was njs applic the application was aware of um the values large medium and small it's because we defined this enum inside um this validator or this um decorator is enum and I pass it this in a pizza size okay so everything is connected now I want to change it to small and click on send yes it's working as expected but there is is an issue here if you see I'm sending something called toppings on top of our um values which is enum price and size by the way if I decide to remove this and click on send I will receive an error size must be one of the following because it's um it's not optional if I go to dto here all these values must be passed not none of them is optional so anyway uh when I send the request with the the um mandatory properties like size price and name but at the same time I add something from my own like toppings and I click Send the API doesn't doesn't um consider it as a security risk or something it responds back as usual but sometimes we need uh we need to prevent that from happening we need to confine the the incoming request to the shape that we expect so if we are expecting only name price and size and we we want to prevent the user from sending anything else like um like toppings or whatever we need to add some logic in order to prevent that user but luckily in njs we can do that so easily by going to the um main TS because it's where we do um root level logic and I can define an object and inside this object I can pass some values for example uh here it's called Whit list listed as oh yeah Whit list as true when we Define Whit list as true we see when I send uh these four values okay when I send these four values uh in the response although if you remember in the controller where is the create this one I'm returning back the body but when I return the body I don't return this value I'm returning all only the mandatory values why because this one was filtered filtered out automatically by our validation pipe because I said the white list to true and also if I want to take it to the next level in security I can say forbid uh for bid nonwhite listed as true in this case any any values or any properties are that are not defined in our dto will be automatically uh not only filtered out but also will uh throw an error let's see in our case here if I click on send you see there is an error bad request and generic error 400 property toppings should not exist so once I remove this and click on send uh expected double quotes oh yeah so now if I click send you see that uh everything is working as expected name price and and size are returning are being returned back so I know that my validation pipe is working as expected now if I want to go to the uh app module uh app module if I if you see here um with I we talked already that the app module is connected to pizza's module but also we have app controller and app service but these services or these controllers are doing nothing actually they are just um created automatically by NJ when we created the application so I need to remove them by removing this and removing this and also removing these two lines and that's it I hope you enjoyed the video and if you did consider subscribing to my channel to get notified about the next videos in this series and also make sure to check out the description box down below where you get access to the GitHub repository of this uh Pizzeria application and it will get updated with every new video also I would really appre appreciate it if you go and support me by buying me a pizza or two that will support my creative work my content and my work thanks for watching and see you next time [Music] [Music]
Info
Channel: Mark Maksi
Views: 164
Rating: undefined out of 5
Keywords: beginner nestjs, nestjs for beginners
Id: f7R9TXz4v-0
Channel Id: undefined
Length: 40min 24sec (2424 seconds)
Published: Wed Jul 10 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.