Transcripts
1. Nestjs for beginners: course Introduction: Hello and welcome to
my course on STS, a progressive Node
JS framework for building efficient and
scalable web applications. Ses is a framework that combines
the best of both worlds, the power and flexibility
of nodes, yes, with the elegance and
simplicity of TypeScript. That's yes, provides you with a modeller actually
tectorial dependency, injection, exception handling, testing utilities and much more. In this course, you will learn how to use
less just to create a blog application with authentication using off
guard cell Mongoose. You will also learn
how to set up your development environment
and installed an STS. Create controllers, services, modules, guards and decorators. Use nests CLI to generate
code and run commands. Connect to a MongoDB
database using Mongoose, the fine schemas, Models, interfaces and videos, and being encoded operations for blog
posts and user actions. Security or endpoints with
JWT authentication and guards handle errors and
exceptions gracefully. This course is designed for
beginners who want to get started with an SES or improve
their existing skills. You don't need any prior
experience with an STS, but you should have some
basic knowledge of Node.JS, JavaScript and a little
bit of TypeScript. By the way, if you want to learn more about NodeJS
and TypeScript, I have another
course on sculpture, covers everything you
need to know about. Notice that course
you'll learn how to use NodeJS for building
RESTful API eyes, real-time applications,
GraphQL servers and more. You will also learn
how to use some of the most popular frameworks and libraries that
work with nodes, yes, such as explicitly
as Mongoose, socket IO type ramp plus
validator and more. That course was designed to prepare you for using Nes Yes, and give you a solid
foundation of nausea skills. So if you are interested in
learning nausea, sorrow, improving your existing skills, I highly recommend you check out my other course
on Skillshare. Now, this nutshell
scores is structured in a particular way that follows the best practices
of web development. It's section covers a
specific topic with a clear explanations,
examples, and exercises. You can also download
the source code for each section
and follow along. You'll also get access to a friendly and supportive community of fellow students and instructors in
Skillshare who are ready to help you whenever
you have questions or doubts. So what are we waiting for? Enroll now and start
learning NES yesterday.
2. generate your first Nestjs project!: Welcome to the first chapter
of loudness js module. In this chapter, we're
going to dive into the exciting world of Nicias and learn how to create a
simple blog application with authentication. I'm inside the
efficient SES website. Feel free to take
a look around and explore wetness
yes has to offer. However, don't worry if you feel overwhelmed because
in this module, are we providing
all the information you need to get started with Nestea will be covering the basics and building a
real-world application. We can start using
Nicias with confidence. Now, what is next? Yes. Lets us is a framework
that builds on top of the popular extra CS
framework for NodeJS. But unlike express, JS provides a more modular and scalable structure
for your application, it also incorporates many of the best practices and design
patterns used in Angular. You do not need to have
any prior knowledge of Angular to understand STS. And in fact, the projects
we built together in the previous module using Node.JS expressed on TypeScript, have already given
you a taste of how this yellow structure
is its applications. In this module, we'll be diving deeper into an STS and how it can be used to build scalable and maintainable
applications. Also utilizes the power
of TypeScript and the latest Angular
architecture to make building server-side
applications more efficient and enjoyable. And this module, we'll
be using the CLI, or Command Line Interface, which is an amazing tool that allows us to easily generate a new project with all the necessary files and directories to get us started. Now, before we
understand this, yes. Cli installed PMPM be npm is a fast disk space efficient package manager for Nokias. It saves your disk
space and make sure you don't waste your time in
installation and maintenance. The APM is also available
in Windows, Linux, and Mac. To stop the NPM, you will need to have either NPM or Yarn installed
in your system. Once you have one of these
Package Manager is installed, go ahead and open your terminal, then you can run the
following command. If you're inside Linux, you will use npm. Install that C, P, and B F. But if you're on side
windows like me, you have to use yarn at that She don't stall PMPM as a
global package, then P NPM. Alright, after that,
you can install the Azure CLI by running
the command npm. Add that G. Then let's see us. Cli, I have both BI and BPM and SES yellow
already installed. So once the installation
is complete in your site, we can use the CLI to
generate a new project. Let's call it blog
does have to do this. We'll run the command nest, then you plug dash. As you can see, we can access the Azure CLI with the
name nest and then use the new tag to generate
a new blog app project. Now hit Enter. Let's just CLI will request you to choose between these
three package managers. So if you installed
PMPM like me, you can choose PMPM, select the NPM and
then hit Enter. But if you didn't, you can choose
between NPM or Yarn. I already did that. So when you finish, you will have a brand
new SES project ready to go within
a blog dash app. So in the root of our project, you will find several
configuration files that are common
to most projects. These files contain important information about our project. That says dependencies and scripts inside the bag is Jason. But one of the most
important advice is the ES lint error. See, this file is used to configure the linting
rules for our project. It helps us to keep our code
clean and maintainable by making sure that we follow the best practices
and standards. That's why I highly
recommend you to install a extension with the name
ES lint sides your VSCode. With this section, you will get real-time feedback
and suggestions on how to improve your code. So go ahead and install AS and extension side your VSCode. Alright, let's go
back to the project. You will also notice
a test folder and the root of the project. This folder contains
two important files, the adjacent file and the
app spec dot txt file. So they just JSON file is
a configuration file for just a popular testing framework
for JavaScript projects. It sets up the testing
environment for your nest yes. Application. Yeah. And for the upper
spec, the ts file, this is an example of an end-to-end test
for your application. So an end-to-end tests are used to test
the empire fall of your application from start to finish to ensure everything
is working correctly. Now the abstract,
the ts file pests the response of the root end
point of your application. It uses the support
test library to send a request to the application
and test the response. This is a great way to ensure your application is working as expected and to catch any issues early on the
development process. Overall, the test folder and the files inside
that play a crucial role in ensuring the quality and reliability of your
Nestea, this application. Now let's go back to
the package.json file. Here we can see several written scripts or commands that we can use to run and manage
our application. These scripts make our
development process much easier and more streamlined. Some of the most
important scripts include the start script. This command is used to start the application in
development mode. When we run npm, npm bland
starting to terminal, it will compile and start the application on
the specified port. Yeah, but I prefer, or all the developers prefer to run these start calling did, because this command here will contain the dice dice watch tag that allows us to
run the application and what changes
in the same time. Now we have also
the build script. This script is used to compile and build the application
in production mode. Compiled version
of the application will be ready to be deployed. And we're going to
get this folder inside the directory
of our project. We have also the test script. We're using the script to run the test cases for
the application. We can use it to make
sure our application is working as expected
before we deploy it. And the maybe a new command
for us is the lint command. This command is used to run the linting process on our code. Linting helps us to maintain ecosystem code style and helps us avoid common
coding mistakes. And let's talk about
the format or Command. This command, the format is used to format our
code according to the rules specified in the
linting configurations inside the US land ARC GIS file. You can play around with these configurations
as you wish. But the default configurations provided by an STS
is more than enough. Yeah, So let's close this. And in general, these strips inside the biggest
adjacent file or very helpful in automating
the development process and making it easier for us
to manage our application. It's important to
understand what each of these scripts stars
and how we can use them to our advantage. Alright, now let's go ahead
to the SRC folder and go through each file inside this folder and
explain the purpose of it. We have the main.js file. This is the entry point
of our application. It creates an instance of the application and starts listening to the specified port. We have also the app dot
module that has file. This is a model that groups
all the controllers, services, vibes and
more and one roof. It's similar to the concept
of modules in Angular. We have also the app
dot controller.js. This is where we define our routes and handle
incoming requests. It uses the greater
is like GET or post, which aren't given
them to app.get or abduct post in expressed. The controller class in
SES is responsible for defining the endpoints and handling incoming HTTP requests. It's method inside
of the controller represents a route
in your application. The methods can handle different types of
requests like GET, post, PUT, delete, et cetera. This is done with the
help of decorators yet, such as the category later, which is equivalent to the
get method in Express. Now we have also the
controller curator. This is used to identify
the class as a controller. This is important
because lets us know that this class should handle incoming HTTP requests. Alright, let's move on to the
abducts services.js file. Now, this is where we
put our business logic. It's a great place to put
any database queries or other complex logic that our
controllers need to use. We have the injectable, the greater this is used
to identify classes that can be injected as dependencies
into other classes. In our example, we have the
App Service that yes class, which is marked as injectable. This does mean that
it can be used as a dependency in other
parts of our application, we can inject the App
Service glass into the controller using the
injectable decorator and then call the get's hello method from the App Service class within our control, as
you can see here. Now, this is a powerful way to manage dependencies
in your application, making it easier to
test and maintain your coat by organizing
your code in this way, you can ensure that
your controller is focusing on handling
incoming requests. Why are the observers class can be used to handle
more complex logic. Right now that we've set
up the project structure, let's run the server and check the browser for the hello
world router response. To do that, we run the
command npm run start, site, our terminal, or PMPM because
we, we've installed that. So be npm, run, start falling, death
and hit Enter. Of course, we need to
navigate to a blog that's up. And then bond the
command once again, be npm run start going in there. Alright, if you'll get
this last line here, application successfully
started, it means that you've successfully
started your application. Now let's go ahead and
open the browser and test for the hello
world about a response. Here, let's navigate
to localhost thousand and wait
for the response. And here we go, the
Hello World string. Now you might ask
how we did that, though inside the controller. Let me collapse this,
this router here, this method represents the
root end point of our API. I can change this by
adding a string inside the get decorator like
this, e.g. hello. Then save. This way. We're going to get the Hello World string
inside the hello route. Let's go back to the browser. Let me first navigate to the root and point
of application. You can see that we cannot get the root end point of our API. And that's because we
changed it to Hello. As you can see, this is
very simple because of the help of the graders
that are inside nets. Yes. Now, we've successfully set up in units yes, Project. And we've got a basic
understanding of its structure and main fights. In the next chapter,
we'll dive deeper into the controllers and services and modals and how to
use them properly.
3. Setting up mongoose: Hello everyone. In this video, we
will start with a pretty structured
project that you will find in the
resources section. So go ahead and download it and open it inside your VSCode. It's important to
take a moment to understand the structure of our project and why we have divided it into
smaller components. Our application is organized
into four main directories, the app directory, and inside that the author, blog, end-user. Each of these
directories contains a set of components
with a specific role. Now the app directory is the main directory for
these three components. And it contain the app
dot model, the ts file. But we're not going to work
with this at this moment. But each of these
directories contains a set of components
with a specific role. These components are further
divided into controllers, services, and schema fats. But the directory is empty
for now because we're going to add a very
specific files and configurations through it. Yeah, but now we're going to work only with these
two components, the blog and the user. So this structure helps us to manage and maintain the
code more effectively, as well as making it easier
to scale the application. Like when we add new components
or expand existing ones, they don't affect the
rest of the system. Additionally, this
detector decoupled different parts of
our application, making it less dependent on the implementation
details of other parts. And lastly, the structured
file organization makes it easier for developers to understand the different
parts of our application, how they fit together, and
how the whole system works, making it the best practice
to follow in SDS development. Now, in summary, our
project structure results in better code management
scalability to cope link, and easier for understanding
the overall system design. Alright, now in this project, we'll be using MongoDB
as our database to store our blog posts
and user information. We work with MongoDB
and honest yes project. We'll be using the
popular MongoDB object modelling library, Mongoose. Mongoose provides a simple
and elegant solution for defining schemas,
validating data, and querying the
MongoDB database with Mongoose will be able
to easily interact with our MongoDB database
and model our data in a way that makes sense
for our application. So let's get started and integrate one goes
into our project. First, we'll navigate
to the MongoDB others website to update
our MongoDB URI. So here, if you don't
have an account, you can click on this drive for EE button
and create a new account. Or if you have an
account you just sign in the clusters section. If you're new to MongoDB, you can create a
new cluster using this button and then choose the shared cluster
in order to get a free plan and then create the cluster by clicking
on this button. Once you've finished From that, go back to the clusters
section and click on Connect, and then connect
your application. And this is the MongoDB URI. We're going to use this URI to connect our ECS project
to the MongoDB database. Make sure you select no GS here. And the latest NodeJS version. Alright, now let's copy this. And then let's go
back to VS code. And inside the file, you will find a
MongoDB URI variable. Go ahead and paste
our URI there. And then we're going
to change the password with the actual password
of our account. So if you have already
your password, you can put it here. If you didn't save the password, you can go back to MongoDB Atlas than close this up
and database access. And then click on
Edit on your account, then click on Edit password. And then here we can
generate a new password by clicking on auto-generate
secure password button. So I'm going to do that. I'm going to copy this. And then make sure to
take an update user. And then go back to VS code. Go ahead and basically password there and then save the m5. Next we're going to
open the terminal. And then we're going
to install Mongoose. Let's run the command
PMPM, then mongoose. And because we're
using this, yes, we're going to install Mongoose. This module is going to
provide us with a set of decorators and other
helpful utility functions for working with MongoDB. Hit Enter and wait
for the installation. Once we have our
modules and installed, we'll go ahead and import
it into our adult model, the ts file, close the terminal
and up here, that's M4. And then inside the
imports array here, we're going to import the
mongoose module and use it in our project by calling
the mongoose module dot for root method. So let's go ahead and write
mongoose module four. And inside this method, we're going to add the
MongoDB URI from process. Mongo DB underscore. But in order to get
access to the empire, we need to use the config
service provided by nest. Yes, we need to
install it first. So go ahead and open again
the terminal side here, use the npm and then add. That says Save to save
as a dev dependency, the Nest CSF. Then config mode. Hit Enter, wait for
the installation. Alright, once the
installation is complete, we can import the config module inside the app module and
control its behavior, the four root method. So let's go ahead
step-by-step and import. Now, we're going to put
this inside the array. Go ahead and add a comma. And then here, right, config module four root. And this method will accept
an object of properties. The first property is global. This property,
it's going to tell config module to make the m-file globally available
inside our application. The second property
is the file path. Now, let's add the
dot file like this. So I'm just added the name. In this case, we are referring to the root directory
of our project. And the conflict model
is going to look for that file inside
the root directory. Alright, now you can add multiple files by
adding an array. And then if you have like not
int and another int file, like maybe, I don't
know anything. You can add it like
that as an array. But for us, we only
have one file, so let's keep it like that. Now as you can see, the config modal class
is a powerful tool that allows us to access environment variable
globally in our project. Does by using config
module for boot method, we can easily configure the module to make the
environment variables stored in the dot M file accessible throughout
the entire application. This means that we don't have to manually ampere
the dot M file in every module or component that needs access
to these variables. Instead, we can simply
use the config service to access the environment variables from anywhere in
our application. This makes it much easier to manage our
configuration and maintain a consistent environment across all parts of our application. Alright, now we've finished
from setting up Mongoose and we're all set to start
working on our application. So in the next video, we're going to create
our blog schema. Aside the blog dot schema, the ts file using Mongoose did that in
the previous projects, but this time is
going to be slightly different because
we're using nest. Yes. So see you there.
4. Designing and Implementing The Blog Schema: In this video, we will create the blog schema in
our nest yes project. We'll start by opening the blood component directory and then they block
schema to ts file. Inside this file, Let's
start by exporting a new class and name it locked. Inside this class we
will add two properties, title of type string and
content of type string. Now we have some areas
here coming from ES and all you have to do
is saving the file. If the errors didn't
disappear automatically, you can go to File and preferences than settings
and search for ES lint. Scrolling down and make sure to enable ES and as a
formatter for your VSCode. And then scroll up up
in settings of Jason. And then make sure to copy all of these lines to
cite your settings, the adjacent file,
then close. This. Still didn't work for you. Make sure to have LLF as the end-of-line sequence.
Your VS, VSCode. You can change it from here, but this will go
back to the default as LLF when you
reopen VSCode to get. So to make this permanent, you can go back to settings and then
search for end of line. Scroll down and make sure to choose backslash n as the
end-of-line character. Then close this test
again the file, if he's still have some errors, go back to prettier RRC and
add end of line equal L F. Now, this is all the
required settings to have auto figs
on Save with ES. And now let's go
back to our schema. So this is just a
simple class and it is not yet a mongoose schema. To make it a mongoose schema, we will use this schema
decorator imported from T S Mongoose. So go ahead and import schema from Nes
Yes, mongoose library. And we're going to place it at the top of our blood class. Like so. Makes sure there are no lines between the class
and the integrator. Now to identify the two properties as
Mongoose properties, we will use another
decorator and imported from the same package. Name probe, and place
it at the top of each property. For the title. Prop in for the content. We can also add some
configuration to its property by adding an object inside the
property decorator. So e.g. if you want the
title to be required, we can add an object and then add the required property
and set it to true. Likewise for the
content property. So I'm going to copy that
object and paste it here. Then save to remove all
the Eastland errors. Now to export the blood
class as a schema, we will import the schema
factory class from this yes, last mongoose
library here, right? Schema, factory. And other but'm going to
export a constant and name it log schema and set it
equal to schema factory. Then create a class method and we're going to
pass the blood class. This will set up
our blog schema. Now, we also need to export blog document type
for this file. To do that, That's important. The hydrated document directly
from the Mongoose package. And then at the top here, we're going to export
a type and name it, plug document and set it
equal to hydrated document. And pass the plug. Finally, to make the schema accessible throughout
our application, we need to go to the app module. Let me first say this
and go to app module. And then we're going to use the Mongoose module
inside the imports array, like so, Mongoose deal. And this time we're going
to use the feature method. And inside it we're
going to pass an array. And this array will
contain Mongoose models. Though it's Mongoose model is an object with two properties. The first property is name. And we can get the name from
the blood class course. You have to import it from blog, blog that schema dot name. And the second property
is the schema property. And we're going to get the
schema from the blog schema and make sure to
import it as well from blogged at
schema, the ts file. Now the Mongo is model.fit
method is used to import Mongoose modals in a specific
feature module in STS. This method takes in two
properties, name and schema. The name property specifies
the name of the model being imported and is usually set to the name of
the model class. The schema property specifies the Mongoose Schema that corresponds to the
model being imported. By using the Mongoose
model for feature Method. We make our Mongoose models accessible within that module. Now, the reason why I had to import the blog schema
here is because the app module that he has file service as a root module
in your nest yes. Project. It's responsible for bringing together all the
different components, controllers, and providers
that make up your application. By importing these modules
into the app module, the ts file, we're making
them available globally. Throw out your application. This allows you to easily reuse
components and providers, making your code more organized
and easier to maintain. When you're creating
a new component, it's important to remember to import it into the app module, the ts file, so that it can be used by other parts
of your application. Similarly, when you create
a new Mongoose model, you will also need to import
it into the app module, the ts file, so that can be used by your controllers
and providers. This allows you to
easily interact with your MongoDB database and perform operations
such as creating, reading, updating, and
deleting documents. Alright, so this
concludes this lesson. And the next one, we will delve into the blog service
that ts file. This is where the real magic happens as we will use
the block model we just created to perform various
database operations from reading and
creating blogposts, updating and deleting them would cover it all
in the next lesson. So make sure to keep your notes handy and get ready to code. I'll see you in the next lesson.
5. Creating The Blog Service: In this video, we'll be
exploring the power of services in SES by using
the blog service class, which has already
been set up with the injectable decorator in
the block services.js file. So before we begin,
I'd like to remind you that all these
setup of this video is already available in the project at pass to the
resources section. So make sure you download it, open it in your preferred
code editor and run PMPM installing the terminal to download all the
necessary packages. With that out of the way, let's dive into the world
of services and SES. So this class will
be responsible for managing all of our
database operations. That says retrieving, creating, updating, and
deleting blog posts. By utilizing the
injectable decorator, we can define this class
as a service that can be easily reused throughout
our application. By the end of this video, you will have a
solid understanding of how services work in SES and how to use them to
interact with the database. So let's get started. Now, in the previous lessons, we have discussed
the importance of the injectable decorator in SDS. This decorator is used to indicate that the
class is intended to be as a service that can be injected into
other components. It is a crucial aspect
of writing clean, modeller and maintainable
code in SDS. By using the
injectable decorator, we can easily manage
dependencies and chair surfaces between different
parts our application. So don't forget to add the injectable decorator before defining your service
class in SDS. With that being said,
it's signed to use the power of MongoDB
inside our service. To do that, we need to import the inject model decorator
from an SES mongoose library. This decorator is used to inject a Mongoose model into
a initiate service, making it easier to perform database operations
on the model. In our case, we want to define a private variable inside the
constructor of this class. Let's plug modal. And it's going to be of
type Mongoose model. To do that, we need to import the Moodle interface
from Mongoose. This interface is a
generic interface that accepts a
mongoose document. Though in our case,
we're going to pass the blood document imported
from blog, that schema file. Now this private variable
is going to be injected using the inject
modal decorator. This, the grader will
accept the blog model name, can get that from
the blog class name and make sure to unfold the blog class blog
dot schema file. Now with this
injectable variable, will be able to perform various database operations
on our blog Moodle, and make it accessible
throughout our service. Now that we have our MongoDB
connection establishes a start creating some methods for performing
database operations. First, we create
the create method. Make sure it is async. This method is going
to be responsible for creating a new block outs. But before we start working
on the method itself, it's important to
note the arguments that the method will take it. Instead of directly taken
in the arguments like so, title string, content, string. It's best practice to create a data transfer objects
or DTO interface in another separate file that will hold the data
that we want to save. This will help us maintain the structure of the
data and prevent any errors that could arise from Anchorage data being
passed to the method. Or this, you will
find a create a DTO, the ts file, save
the details folder. This file we're going
to export and create an interface with the name
create blog, the teal. This interface will hold the
properties we want to save, the title of type string and
the content of type string. Save this file and close it. Go back here, remove
the title and the content arguments and
replace them with one argument, create blog, deal of type. Create log D TO
make sure to import that from the Tiers folder
and from the creator DO file. Now inside the create method, we need to create an
instance of a blog model. So go ahead and create
a blog constant. Use the new keyword. And then the this keyword
to access the blood model. And then we're going to pass
the create blog detail. This will create an instance
of the block model. Then we have to save that
and return it to the client. Return a weight. Blog dot save. Next, we're going to create another method with
the name update. This method is going
to be responsible for updating a specific blog post. First, we need to create
the Update blog DTO. So go ahead and open the
updates are DTO, the ts file. And here export interface
updates, plug the deal. Now in order to update
this specific blog post, the client needs to send the ID. So we're going to wait for
underscore ID of type string. As you know, Mongo stores
id with an underscore. So make sure to add that. Then for the title
and the content, we're going to receive that
inside a client props object. And the title here is of type string and the content
type string as well. But we want to give the client the freedom to update
only title or only. But let's make these
properties optional by adding the question mark before the colon in front
of each property. Save this file, close it. Here, save the update method. Let's add the update
blog that TO argument. Going to be of type
update vlog video. Make sure to import that
from the updated video file. Now save the update method. We're going to use the
find one and update method from the mongoose library to update the blog
post in the database. So we're going to
return a weight, this dot blog model, dot find one, and update. Now this method, we'll first accept an object
as a filter query. This object will filter the blog document with
the underscore ID. And we can get that from
the Update blog DTO dots. And the risk of ID. The second argument
is going to be the updated document
or the update query. Of course you can get
that from updates blog dto dot client prompts. The last argument is going to be an object with a new
property set to true. The new property is
going to tell the find one and update method to return the data document
instead of the old document. Next, let's create
an async method, and they may get one. This method will take the ID of the blog post as an
argument of type string. And it's going to return the corresponding blog post
from the database. So inside here, right,
return, oh wait. This block modal, find one. This method will
accept an object. And inside it we're
going to query our blog post with
the underscore ID. It should be equal
to the argument ID. The next method is
going to be good. Oh, and it's going to
be responsible for returning the blog
posts and the database. Now this method will not
accept any arguments. And instead it's going to
immediately return 08. This dot log model. Find by ID method has to accept an empty object in order to return all the blog
posts and the database. And finally, we're going to
create the delete one method. This method will take in
the ID of the blog post as an argument of type
string and delete the corresponding blog post from the database using the find
one and remove method. Go ahead and return a weight, this blood modal that 0.1. And remove and remove the blog document with the underscore ID equal
to the argument ID. Now let's go and set the
return type of each method. The create method is
a promise that will resolve a document
of title block. For the update method. Same thing. Promise. That will resolve the
blog document here. Same thing as well. Promise. Plug for the get. All. This is going to be a promise that will resolve
an array of blocks. For the delete one,
we're going to send back no or a Boolean. You can set that as an resolve type for this method or you
can leave it empty. So let's save this file and
that's it for this video. With these methods, we now have a functional servers that can perform all the required
database operations, but I will upload component. In the next video. We'll use this service and
the blog controller to define the endpoints of our API. So stay tuned.
6. Creating the Blog Controller 1/2: Welcome back. So far we've successfully created
our blood component, which includes the blog
schema and the Blood Service. Now it's time to work
on the blog controller. You will find the
starting point for the project in the video
resources section. To get started, simply
download the project and open it in your
VSCode editor. And before you start coding, Be sure to run PMPM installed in the terminal to install all
the required dependencies. In this video, we'll be creating the blog dot
controller.js file, which will act as
the bridge between the front-end and the
back-end of our application will use this file to define
the various endpoints for our blog component
and also integrated with our blog service to
perform database operations. So let's get started. Our next step is to dive into
the world of the grapes. Specifically, we'll be taking a look at the
controller decorator. This decorator will
allow us to make the blog controller accessible
from the router of RBI. However, if we want to
change the router from the root to e.g. blog. Like this. We can simply pass
the string blog into the control or a decorator. This way, we'll be
able to control the path where our blog
controller is accessible. Next step, we need to import
our blog service in order to use all the database methods we created in the last lesson. To do that, we'll add the import statement at the
top of this file and import the Blood Service from blog that service the ts file inside
the block controller. Let's create the constructor and define a variable
called blogs. Service will set its type
to plug service class. This way, TypeScript
can understand the properties and methods available to us from
the blog service. This makes our code
easier to write, maintain, and free of mistakes that would
occur at runtime. It also helps with
code completion, allowing us to write code
quickly and accurately. Now let's create
the Create Router. First, we'll add an async
method name and create. But just having this method alone create an
actual router works. We need to decide what type of request this
router will handle. In our case, we want to send the blog information from
the client to the server. So we'll implement
a post request. We can do this easily with
the post decorator that could be imported from the nest
she has come in package. So go ahead and do that and place it at the top of the
create method, like so. Now, the most decorator can accept an optional
string argument which represents the router
path where they create router will
accept requests. If we leave it blank, the client will send the request to local
host 3,000 block. However, if we're going
to add multiple routers, it's better to make the
Create Router reachable through the router path create. So let's do that. Now the create method will
receive a body argument. The body argument
is going to be of type create log detail. Makes sure to import the IO interface from
the creator TO by. Now, adding the body argument inside our create method is not enough because we need to make a connection between the
request body and this argument. That's where the body
decorator from Nes Yes, come in comes in, import it first from an SES
coming baggage. And we're going to place it
inside the argument list of our create method before
the body argument, like so. And now finally, we can use
the blog service to create the blog document and return
it to the client side here. Return a wait list, dot blog, service, Create. And then we're going to pass the body argument to
the create method. When we save the file or
the areas will disappear. Because the body argument
has the same type as the create blog DTO argument
of the create method. And with that, we have completed the setup of the Create Router
in our blog controller. Congratulations. In the next video,
we will continue working with the
blog controller and implement the rest
of the routers such as update, delete, and get. These will allow us to perform all the necessary operations on our blog documents
will also go over how to handle errors
that may occur during these operations and make sure our application is
robust and reliable. So stay tuned for the next video and let's keep
building together.
7. Creating the Blog Controller 2/2: Great job on reaching
this far. In the lesson. In this next segment, we're going to take
a look at the rest of the block controller class. Let's start by creating
the update Troutman. First, we'll create an
asynchronous method with the name of date. This method will take
in a body argument. So go ahead and use the body decorator and create the body argument and
give it the type of update. Vlog video and make sure to import that from the video file. Now this method is going
to receive a post request. So let's use the post integrator and give it the path update. Aside this method, going to call the update method on
the blog service. So go ahead and return 08. This service that update and
pass in the body argument. Now, this update method is going to update the blog
document in the database. Let's move on to
the get one router. Go ahead and create an
asynchronous method again, and they may get one. This method will allow us to retrieve a single blog
post from the database. And it will take in an ID
argument of type string. This id will be passed in as a parameter to
the router path, which will define using
the get decorator. So go ahead and import
the get degraded from nest yes slash
common package. And then inside here we're
going to give it a path of post slash ID. And then inside the arguments
list of this method, we're going to use
another decorator to extract the ID from
the router path. This is the greater
is named para. So go ahead and import that as well from the mesial
is common package. Then inside it we have to name our parliament or in our case, our parameter has the name id. Now, we'll use this
method to call the getline method
on the blog service. So go ahead and return
this block service. Get one and pass in
the ID argument. This will retrieve the desired blog post from the database. Next, we'll create
the Get or router. This method will allow us
to retrieve all dog oh, it's from the database. First we'll create, again an asynchronous method
with the name gets. All. This method won't
take any arguments as it will simply retrieve
all posts from the database, will define the
router path using the get decorator
followed by the path. Finally, we'll use
this method to call the get method from
the block service. So go ahead and return 08. This block service, service that get all this will retrieve all blog
posts from the database. Now, last but not least, we'll create the
interleaved router. This method will
allow us to delete a single blog post
from the database. First, we'll create an
asynchronous method and name it, delete. This method will
take in an ID as an argument of type string. This id will be passed in as a parameter in
the router path, which will define using the
delete the crater at the top. Import and use the
Delete decorator, followed by the path delete large colon ID to get the ID
of the desired blog post. And then we're going
to use the paran, the greater to extract
the ID from the request. Now, we'll use this
method to call the delete method on
the blog service. So return, await this
block service that delete one and pass
in the ID argument. This will delete the desired
blog post from the database. And with this final method, we've now completed the
blood controller class and all of its routers. Great job on following along and implementing these important
pieces of our project. By the way, the ID
argument is not necessary to be exactly. Similar to the parameter name? Yeah, it can be anything
like e.g. underscore ID. Yeah. And here you have to change
that to underscore ID. But the parameter inside the
router path should be equal to the parameter to the name of the parameter inside
the program decorator. Otherwise you won't be able to get the id from the
router package. Okay, Now that we've
finished creating all the routers for
our blog controller, it's important to think
about error handling. After all, things can go
wrong in any application. And it's crucial to handle these situations and appropriate
and professional way. In SDS, we have several
ways to handle errors, including the use of
exception filters, vibes, and guards. In this lesson, we'll be
using exception filters to handle errors in our
blood control or methods. First, let's sample the
HTTP exception class from the ***** yes,
coming package. So at the top import
HTTP exception, this class allows us to throw an http related
exception and send a specific status code and
error message to the client. Next, let's run our code
inside a try catch block and through an HTTP exception
inside the guts plot, e.g. inside the create method. We can do something
like this. Try. Then here, catch. And let's gets the error. Then take this line and put
it inside the try block. And in case we have any others we're
going to use or we're going to throw a
new HTTP exception. And the HTTP exception class will take a message argument. So this musters can be anything. So in our case, we don't know what went wrong
inside the log servers. Create that create method. So we're going to send something like something when trunk. And then we have to pass
in another argument. This argument will be
the HTTP status code. And we can get that
from another class with a name http status. Makes sure to import it as well. From an SDS come. This class holds a
lot of other types. And the one we're
going to choose here is the internal auto. Save this to remove all the errors of
yes-and as you can see, error handling in SES is way simpler than a pure
NodeJS application. We can implement
this same pattern in the rest of the methods. Catching the errors and sending a proper error message and
status code to the client. By implementing error
handling in this way, we ensure that our
application will behave properly even in case of others providing a
better user experience and keeping our code
organized and professional. And now that's it
for this video. We've now completed the
blog controller class and all of its routers will find the final result of this video lesson attached
to the resources section. So go ahead and download it in case something went
wrong in your code. The next video,
we're going to test our application using
the postmen software. So see you there.
8. Test the Blog Component with postman: In this lesson, we'll be testing our blood components using
the Boltzmann software. Before we start testing, let's
make sure that I'm putting both the blue controller
and the blog service inside the app modelled
the ts file to do that. First open up App Model and then inside the
controllers array. Let's add the blood controller. Of course you have
to import that from blog dot
controller.js file. For the service. We're going to put that inside the
providers array. So go ahead and write
blog service and import it as well from
its corresponding file. Now, this is important to ensure that the
component is fully integrated into our application and can be accessed
by post them. Now, before we run
our application, we have to make sure to import the file before everything else. So go ahead and put this line as the first item of the array. Because if you don't do this, you will get a database error. Alright, let's save
this file and close it. Then open up the terminal side here and run the command npm
run, start calling diff. Alright, As you can see
how an SES application is running and waiting for
connections on port 3,000. Now let's open our postmen and make sure to create
a new workspace. And then here inside
the collection section, click on New button and
then choose HTTP request. Now we're going to start
testing the Create Router. Do this. Let's choose the post
request from this list. Here, Let's pass in the
http localhost URL, then the router path
of the create method. So the grid method exists
inside the blog Create. Now in the body section
of the request, we're going to send
a JSON payload that represents the blog
post we want to create. You do that, click on row. And then here, change dx2, json. And then let's create an object here and
pass in the title. So title is going to be
blogged or test blog. And the content is going
to be test content. Now, to send this request
click on the Send button. Now, as you can see, we received a response
with a status 200 and the adjacent object representing the newly created blog
post with the id, the title and the content,
and the underscore. Underscore V represents the
version of this document. Now we're going to use the ID of this block document
in the next routers. So let's go ahead
and copy this ID. And we're going to save it as an environment variable
inside Postman. So click on the
environments section. And then inside here, Let's name this
blog underscore ID. And going to set the value
to the blog document ID. Let's click on the Save button to save this
environment variable. Then let's go back here. And we're going to
get one router. This router retrieves a
single blog post based on its ID to this router
will send a get request. So let's change this to get. And then we're going
to send a request to the path Blog, then post. And then we're going
to send the ID that we just saved as a global
environment is out inside Postman to
access that environment variable to curly
braces like this. Then 2s block underscore ID. We don't need to send any body. So go ahead and choose none here and then send the request. And here we go, we've got
our guest blog document. Now, let's go ahead and
test the get all router. This router or retrieves all the blog posts
stored in our database. We currently have one blog post. So we're going to
get an array of one blog document
that has this router. Makes sure you have the
cat request type here. And then change this URL too. Blog, then 0, send the request and you should get an array of
one blog document. But as you can see here, I
have multiple blog documents because I've tested this
before start recording. So I have multiple
blog posts here. But as you can see, we have our last block document as well, represented inside this array. So in your case, you'll get only this block document there. Now, finally, we're going
to test the delete router. This router or deletes a single blog post
based on its ID. So when we send the request, I would get an array of all
of these logged arguments. And this blog document
won't be there. It will be deleted. For you. You will
get an empty array. Let's go ahead and test
that blog and then delete. In. Let's add our blog ID, two curly braces and then
select block underscore ID. Make sure to change the
request type to delete. Let's send this. And here we go. Actually we got the deleted blog document. Yeah, we didn't receive
site or application. We didn't send back an
array of documents. So here, the delete one. This method will only send
back the blog document and it will send back an null if it didn't find the
requested document. Yeah, let's go back
here and test again the get all router and check if this block document was
really deleted or not. Let's move this. And instead, let's call blog slash bowl and change their gross to get
than ascenders. And as you can see, the test log is not so n inside this array. So it was really deleted. And by that, we have tested all of the routers and
the blog controller using the postmen
software by sending HTTP requests and inspecting the responses from the server, we can be confident that our component is
working as expected. So please make sure to import the controller
and the block servers here. And to put this spine jump or the M file as the first
item of the array. In the next video,
we're going to start working on the user component. So cilia.
9. Designing and Implementing The User Schema: In this next lesson, we'll be focusing on
creating the user schema. The user schema will
be used to store the information of registered
users in our application. To start with on only be adding the email property as
a schema property. This will simplify the process of signing aim for our users. Now, I want to challenge
you to try building the user schema on your own
before watching this video. This will help you to
understand the process of creating your schema and
the logic behind it. And then after you've
given it a try, what's the video to see this step-by-step process
and creating the user schema and make sure to follow along to
avoid any mistakes. Now let's get started inside the user dot schema,
the ts file. Go ahead and export a new
class and name it user side. This class will have an innate
property of type string. Now let's import these
schematic rater and pour it schema from this
yes Mongoose package. And then place it at the
top of the user class. Like so. Then for the email broad
need the prop, the grader. So go ahead and import that and place it at the top of
the e-mail property. This property is
going to be required. So go ahead and add the required property
inside the prop decorator. And then we're going to
export our user schema. Let's do that at the button. Create a constant
named user schema and set it equal to schema. Bacteria, makes sure to import that from this yes, fungus. Then use the method create for class and pass in
the user class. Now the last step is to explore a user document
type from this file. To do that, That's export type
and name it user document. And then use the
hydrated document and pulled it from
the Mongoose package. We're going to use this type to create a mongoose
document of type user. Now let's save this file
and go to the app module, the ts file here, and add our newly created
Mongoose model inside the mongoose module dot for feature method
inside this array. Here, create another object, m plus n, The name. This time the name
is going to be extracted from the user class. So make sure to unfold
that from user schema and then pass in the name. And we need the schema is going
to be set to user schema. Makes sure to import it as well from user dot
schema, the ts file. Let me save this file now. And as you can see, there
is nothing complicated about building a mongoose
schema using SDS. We've done this in the previous lessons and
we've done it again here. I hope that you was successful on building
the user schema by your, oh, now that's it
for this video. I want to keep it short. And in the next
video we're going to start working on
the user service. The user service will only
contain a or create method, but we're going to deal
with authentication using JWT tokens or
JSON Web Tokens. So stay tuned and see
you in the next lesson.
10. Creating The User service: In this next lesson, we'll be diving into building
the user service will be focusing on creating just
the create method from now. But you should feel
confident in your abilities to continue building the other
methods after this lesson. Now to challenge yourself, you can try building
the create method on your own before
watching the video. By doing this, you can
reinforce what you've learned and apply it
to a new scenario. And you can go beyond
that and try to, when creating the create method, tried to send back a
JWT token to the user. This will be a great
opportunity to strengthen your understanding of
creating services and SCS. So get ready to roll up your sleeves and dive into
creating the user service. We're going to start by creating our constructor inside
the user service. Inside it, we're going to
inject the user model. So to do that, first, let's create a private
variable and name it user model and give it the
type of model imported from Mongoose package and
pass in the user document as Mongoose document tab for that as well from the user
dot schema, the ts file. Now by defining the
user model like this doesn't mean that we injected
it inside our user service. So to do that, we'll use the decorator and
checked Moodle. Import that from the
Nazis slash Mongoose. This decorator will
accept the model name. We can get that from
the user class name. Make sure to import
the user class from the user looks
schema, the ts file. Now by this, we've successfully injected the user model
inside our user service. Now we can use it inside
the create method. So it's going to be an async
method with the name create. And this method will accept an email of type
string as an argument. And inside that we're
going to create a new instance of
the user document. To do that, we'll use the
new keyword and then use the UserModel class that
we've injected it inside that will use their
service to create a new user document instance by passing in an object
with the property email. Now, we're going to save our user document
using the save method. But this time we're
going to hold the safe document inside a
constant named saved user. Then, oh, wait, for
these safe method. Now, the reason why I created this saved user
constant here is because we're going to use the
user document data to generate a JSON Web Token and save the user
data inside it, and then send it
back to the client. So in the next line, we will return an object
with the property Jason or JWT token. This property will hold
the JSON web token string. Now, to do that, to generate the JSON
web token will need to understand what a
JSON Web Token is. Simply put, a JSON
Web Token is a way to securely transmit
information between parties as adjacent object. In this case, the
information would be an authentication token
that identifies the user. After a user logs
into our application, we will return an object
that contains the JWT token. Now this token will
be used to authorize the user to access
protected routes. But for now, let's focus on generating the actual JWT token. And for that, we need to
install some new dependencies. So open your terminal. Here. Let's run the command PMPM. That's does save. Then add ness G, S plus T W T. This package is a
utility package that helps us with GW t manipulation. The second package
is going to be the passport JWT packets. Now this bucket is
the passport package that implements
the JWT strategy. We're going to use it when we start protecting our routes, using authentication guards to prevent unauthorized
users from using our PR. Now, run this command
and you should get these two dependencies installed
inside your application. And after that, you
have to install the TypeScript types of the
package passport does JWT, and makes sure to install
them as a dev dependency, using the desk has
saved as div tag, and then add types, passport, that's T W T. And hit enter and complete the
installation process. Once you have these dependencies installed inside
your application, go ahead and open
the app module, the ts file aside here, and we're going to import our JWT module so that can be used across
our application. To do that, we'll first
import the JWT module from the packets at
Nest GS slash JWT. And then inside
the import survey, we're going to use
the JWT module. Then resistor. Here, we're going to pass in an object with some
configurations. Now, the first property inside this configuration object
is going to be the secret. Here we will save our
JWT secret token. Now the secret token
is used to decrypt the JWT token and extract
the user data from it. So the JWT secret token plays a crucial role in the
authentication process. So we have to save that
token inside the m file. So go ahead and open that. And you will find a JWT
underscores secret valuable. You can put here any
random characters. And then save this file. Go back here. And let's
use that environment variable from the
process that object, then dot DWT under
underscore secretes. The second property is going
to be the sign auctions. This property will be an object with some other
configurations properties. One of these properties is
the expires in property. This will define the
period of time in which the JSON web
token will be valid. Or in another word, to define the period of time in
which the user will be authenticated in our
application and when he should login again to get
a new JSON Web Token. So we're going to set
this to two days. Then save the app module
and close, and close it. Aside here we're
going to generate the JSON web token using the JWT surface that is coming from the SES slash DWT library. First, it's important
on the top of our file. And inside the constructor
of the user service, let's create a new variable, name and GW t service and
set its type to JWT service. Now go back to our JWT and
property and let's use that service to sign a new JSON web token with
the safety user data. So the same method is
going to accept a payload that can hold any
properties you want to save about the user
inside the JSON web token. So in our case, we want to save the user ID. We can get that from the saved user constant, that
underscore ID. And because the underscore
id is of type Mongoose ID, we have to change that to a string using the
toString method. Now the next property I
wanted to save is the email. Can get that as well
from the users saved or the safety user constant dot n. With this final piece, we've successfully
finished our user service. In the next video,
we're going to build our user controller and
create the Create Router. So see you there.
11. Creating The User Controller: Welcome to this video where
we will be focusing on building the user controller
in our SES application. In the previous lessons, we have created the user
schema and the user service, which will now serve as the foundation for
the user controller. The user controller would
be responsible for handling incoming HTTP requests
and directing them to the appropriate
service method for processing. Now, just start, we will add the string user inside
the control or decorator. This will allow us to create a specific endpoint
for the user controller. By using the
controller decorator, we are defining the base route
for our user controller, which will allow us
to easily manage and organize our API endpoints. Now, let's add the user service variable
inside the constructor. So go ahead and create a private variable and
name it User Service, and set its type to
user service class. Then we're going to create an asynchronous method,
name it create. This method will
accept a post request. So go ahead and import and use the post decorator at the top of our create method and inside it, give it the path create. Now this method or this router
is going to accept a body. And we can extract the body
using the body the greater. So go ahead and
import it as well from the nest yes,
common package. And let's define
our body argument. So our body argument is
going to be an object that contains an email
property of type string. Now here we're going to
return 08, this user service. And we're going to use
the create method inside the user service to create
a new user document, save it to the database,
and then return. The JWT token will go into Bus in the email
that is inside the body. And with this, we've
successfully created the user controller
and the Create Router. So the user will
be able to create a new account using
the create endpoint. And then we're
going to send back a JWT token to authorize him. By only sending the
JWT token doesn't mean that our
application is fully protected from malicious use. It's important to
remember that more steps need to be taken in order
to secure our application. So that being said,
in the next video, we will be exploring how we can protect our blog controller from unauthorized users
using a JWT of God, which acts as an
authentication middleware. With this implementation,
we can ensure that only authorized users are able to access our endpoints and protect our application
from malicious use. So let's keep this video short and see you
in the next one.
12. Implementing authentication with Auth Guards: In this lesson, we will
be learning how to implement JWT strategy
and honest yes, obligation and protect
our controller from unauthorized user is
using a JWT off guard. But before we dive into
the implementation, let's have a quick
introduction on cards in SES regarding STIs and execution contexts that
adds as a middleware and checks whether a request is authorized to access a
particular end point. So using this garden, we will be able to check the, if the JWT token is valid or not and extract the
user payload from it. Now that we have a basic
understanding of JWT cards, we need to start by
installing a new dependency. So go ahead and open your
terminal and run the command PMPM, save lives, passport. This is very important
package as it will be responsible for extracting the JWT token
from the header and decoded. And then if only dated
and provide us with the data that was
saved inside it. Once you've finished installing
the passport package, go ahead and close
the terminal and then make sure to download the starting point
of this project that is attached to the
resources section of this video into your system. And then inside the Earth
folder you will find two files. In this moment, we're
going to work on the GWP strategy, the ts file. Here we're going to
export a class with a name JWT strategy. And this class is going
to be injectable. And how we can make
it injectable, of course, with the
injectable decorator. So go ahead and add the W, this class or the
injectable decorator and imported from an
SES slash comment. Then this class will extend
the class passport strategy. As I said, early, early password package is
going to be responsible for extracting the JWT token
from the header and decoded, and then provide us with the data that was decoded
from the JWT token. Now, this class, it's going to accept another utility class
with the name strategy. We can import that
from passport dash d, t. Now let's go ahead and create the constructor of this class. And inside the curly braces, we're going to use
the super method. Now, the super method
is used to call the constructor of
the parent class. Morning super inside the
constructor of the subclass, which is the JWT strategy, we are allowing it to inherit the properties and methods
from the parent class, which is the passport strategy. This helps in creating more organized and
maintainable code. Whenever you extend
another class, you have to use the super
method to make sure that your subclass is inheriting all the properties and methods
from the parent class. So this method will
accept and object, and this object will go
into add some properties. The first property
is the JWT request. This property will tell
the password class how he can extract the JWT
token from the request. We want to extract the token from the header as a
barrier or a token. To do that, we're going to use another class with
the name extract JWT imported from the
password dash g, DWT. Then this class provides
us with a method with the name of header
as barrier token. With this method,
our Esports class, which is going to
extract the token from the header as a barrier token. Now the second argument
is going to be ignore exploration
and set it to false. We're turning the best
board class to not ignore the expired token. So if the user sent an expired token to the API will reject his request and send back
a bottle one response. So unauthorized
request response. Now the last property
is going to be secret or key property. This property will hold the JWT token secret so that the passport holders can
decode the JWT token. We save that inside the
file as an input variable. Usually process that aim
to import the JWT secret. And then we finish setting up our passport configurations. Now we can go ahead and create a method inside the
GW strategy class. This method is going to be N N synchronous method
with the name body date. This method will accept a payload and all we
have to do is has seen the payload
to the next router by simply returning the
payload from this method. Now we can put the type
of the payload goes. We already know the shape of
this payload because we have saved the payload inside the JWT token with
two properties, the user ID and email. And both of them
are of type string. So let's add a colon
and an object with property user id of type string
and email of type string. Now the passport class, we build a user object based
on the return value of the validate method and attach it as a property on
the request object. So to move on from this, let's go ahead and open the
JWT Asgard, the ts file. And here we're going
to build our DWT. So this Guards is going
to be a class GWP of God. And this class is going to
be an injectable class. They'll go ahead and use
the injectable decorator. And we're going to extend another class with
the name of God. You can import that from
SES plus passport packets. This guard class,
it's going to accept the type of the
authentication strategy. In our case, we're
using JWT strategy. So go ahead and write DWT inside the Earth and then save
this file, close it. Those the GW strategy, the ts file, go back to
our block component. And we're going to implement the start to the create method. So we're going to prevent
unauthorized users from creating blog
posts inside our PR. So to do that, let's use
the grader you discard, which will be imported
from the nest zs less common packets. And then here we're going to
use the JWT off guard that we've created
inside the officers DWT that I saw that
card, the ts file. Then let's save this and then
let's go to the app module. And here we have to import our JWT strategy class inside the providers array
so that it can be accessible throughout
our application. So go ahead and add another
item and write JWT strategy. Makes sure to import that from of slides JWT dot strategy
and why we're here, let's import the user
controller as well. The controllers array
and the user service. And say the provider is Eddie. Alright, let's go back
to the blog controller. And by implementing the
off-guard, like so, we are protecting
the Create Router from unauthorized users. Now we can add an extra layer to our authentication by
adding a user property inside the block
schema so that we can know which user has
created the blog document. So we can say the user schema, Let's add another probe
and make it required. And name this property user. Now this property is going
to be of type user class. Make sure to import that
from user schema file. And also this property is going to be a reference
to the user document. Now to do that, this object, we're going to add
the type property and set it to Mongoose. Make sure to import the Mongoose package
from mongoose and then select schema types object ID. Because we want to refer to the user by its ID and then add the href property to set the reference of this
product to the user model. Then save the blog schema, close it and go back to
the flow controller. And inside the create method, let's extract the user
object from the request. Can do that inside the arguments list of
the create method. And by using the reg decorator, make sure to import it from
the SES common package. Now this decorator
is going to give us access to the request and we're going to take the
user object from there. So inside the create method of the blog service, let's add an, especially in an object
and the object here. And add a user property
coming from the request user. And then add a question
mark there because the user object
can be undefined. Then select the user ID. Now we have to go to
the block servers. And inside the create
method here are inside the Creative Blog DTO interface. We have to add a user ID
property of type string. Save the created
TO go back here. And when we save, all the arrows should disappear. Right here. We have to change
this to user ID. Now inside the other
routers, like the update, we can perform an operation
to check if the user inside the requested block document has the same user ID as the extracted user
ID from the JWT token. We can do the same thing inside the delete one router here. I will leave that
as a challenge for you to practice your nest yes. Scales. It should not be that hard. You only need to read the blog document from the
database, the user prop, and check if it is equal to the user ID extracted
from the token. If so, then send back
the blog document or allow the update action on
the requested block document. So with this, we've
finished creating our blog controller and implementing authentication
inside-out application. You will find the final result attached to this video
resources section.