Before you can do that To complete this action, sign in to your Community account or create a new one.
If you’ve worked on a Node.js application, you may have noticed that it became more difficult to maintain over time. The more you add new features to the application, the larger the codebase becomes.
Nest.js is a server-side Node.js framework for building efficient, reliable and scalable applications. It provides backend applications a modular structure for organizing code into separate modules. It was built to eliminate disorganized codebases.
Heavily inspired by Angular, Nest.js was built with TypeScript and uses Express.js under the hood, which makes it compatible with the majority of Express middleware.
In this post, you’ll create a small RESTful API that enables users to fetch, create and delete books in a bookstore.
To complete this tutorial, you will need:
Understanding the Building blocks of Nest.js
The following are the building blocks used when building Nest.js applications:
We’ll start by looking at controllers. Like most web frameworks, controllers in Nest.js are responsible for handling any incoming requests and returning responses to the client side of the application. For example, if you make an API call to a particular endpoint, say , the controller will receive this request and based on the available resources, it will returned the appropriate response.
Nest.js was structured in a way that the routing mechanism is able to control which controller will be responsible for handling a particular request.
To define a controller in Nest.js, create a TypeScript file and include a decorator as shown in the following code snippet:
The prefix of within the Controller decorator will prompt the to handle any GET request within an application and return the appropriate response as specified. Other HTTP request handled by the controller includes , , as we will see later in the tutorial.
Once a controller is created, it needs to be added to the module definition before Nest.js can easily recognise it. This could be the root or any other module created within the application. More about this in the module section of this post.
Now let’s look at providers.
As mentioned earlier, Nest.js was heavily inspired by Angular and similar to an Angular application, you can create a provider and inject it into controllers or other providers. These providers are also called services, and they’re designed to abstract any form of complexity and logic.
The provider created above is a class with two methods and , which can be used to create and return all users respectively. And to easily help with type checking an interface was used to specify the type of elements that should be received by the methods.
Finally, let’s look at Modules. Modules let you group related files. They are Typescript files decorated with decorator. This attached decorator provides metadata that Nest makes use of to organize the application structure.
Each Nest.js application must have at least one module, usually referred to as the root module. This root module is the top-level module and usually enough for a small application. It is advisable to break a large application into multiple modules as it helps to maintain the structure of the application.
If you have an application that manages a lot of data or functionality about users , you can group the controller, services, and other related files into a single module, like :
In this example, we are exported a that contains both the and . With this in place, we can then proceed to import and use the within the root module of the application as shown in the following code snippet:
There are a few other important concepts in Nest.js:
- DTO: Data transfer object is an object that defines how data will be sent over the network.
- Interfaces: TypeScript interfaces are used for type-checking and defining the types of data that can be passed to a controller or a Nest service.
- Dependency injection: Dependency injection is a design pattern used to increase efficiency and modularity of applications. It is often used by the biggest frameworks to keep code clean and easier to use. Nest.js also makes use of it to basically create coupled components.
With this pattern, it is very easy to manage dependencies between building blocks like controllers, providers and modules. The only thing required is to define the dependency for example a in the constructor of a controller as shown here:
With some of these concepts briefly covered, you can now proceed to the next section, where you will put all the knowledge gained so far in this post into use as you will learn how to seamlessly build a RESTful API using Nest.js.
As stated earlier in this post, you will create a sample application that will help you get a good grasp on some of the core concepts of Nest.js.
This application will be specifically for a bookstore. At the end of the post you would have created a micro-service that will enable users to create and add a new book with few descriptions to an existing list of books. This could be from a database, but to ensure simplicity in this post, we won’t really be connecting our application to a database yet. But instead, we will make use of a mock data of books and once a new book is created, we will push and add it to the list.
Step 1 – Installing Nest.js
In order to scaffold a new Nest.js application, you will need to globally install the Nest CLI application. It is a command-line tool specifically created to craft a new Nest.js app and provide access to several commands to generate different files and produce a well-structured application.
Apart from using the CLI tool, you can also install a new Nest.js application by cloning the starter project from GitHub using Git, but for the purpose of this tutorial run the following command to install the Nest CLI:
This will give you access to the command for project installation and other project specific commands.
Next, run the following command to install a new project named within your development folder:
You will be asked a few questions during the installation, just follow the prompt and respond accordingly. Next, once the installation is complete, switch your working directory into the newly created project:
Start the application with:
You can also run the followingcommand in order to use Nodemon for the project:
Navigate to in your browser and you will see the Hello World! message as shown in the following image:
With the project started, let’s create the root module.
Step 2 – Generating a Module
Let’s generate a module for the bookstore. To do this, you will leverage the Nest CLI’s file generator. Run the following command to scaffold a new module for the application:
This creates a new folder named within the folder. Within the folder you will find a file:
This was generated by the command and the module has also been added to the which happens to be the root module of the application.
Next, you will create routes for the endpoints
Step 3 – Creating Routes and Controllers
As mentioned earlier, routes exist in controllers, so you need to create controllers that will handle individual endpoints. Again, use Nest CLI to generate your controllers, run the following command:
This creates a controller inside the folder.
Since we won’t be connecting to the database for now, create a sample mock data for the bookstore. Under the folder, create a subfolder named and within the newly created folder, create a new TypeScript file named and add the following code in it:
Next, you will create a service to hold all the logic for the bookstore.
Step 4 – Setting up a Service
Run the following command to generate a service:
This command will create a new file named within folder.
Next, open the newly created file and paste the following:
First, you imported the requires modules from Nest.js and also from the mock data you created earlier.
Next, you created two different methods named and to retrieve the list of books from the mock data and to fetch just one book using the as a parameter.
Next, add the following method to the immediately after the method:
The method above will be used to push a new book to the existing list
Finally, add the last method to delete a particular book using the as a parameter:
Step 5 – Injecting the Service into the Controller
Here, you will use dependency injection design pattern to pass the into the through a constructor. Open the created earlier and paste the following code in it:
First, the important modules were imported from and you also import both the and respectively. CreateBookDTO is a data transfer object, a TypeScript class created for type-checking and to define the structures of what an object looks like when creating a new book. We will create this DTO in a bit.
Next, you used to inject the into the controller and created four different methods which are:
- : Used to fetch the list of all books. It has decorator attached to it. This helps to map any request sent to /books to this controller.
- : Used to retrieve the details of a particular book by passing the as a parameter.
- : Used to create and post a new book to the existing book list. And because we are not persisting into the database, the newly added book will only be held in memory.
- : Used to delete a book by passing the as a query parameter.
Each of the methods has a special decorator attached to it, which makes it very easy to route each HTTP request to a specific method within the controller.
Step 6 – Defining The DTO
In the previous section, you made use of a data transfer object called . To create it, navigate to the folder and create a new subfolder name . Next, within the newly created folder, create another file and call it and paste the following in it:
You are almost done with the application. Navigate back to the file you created earlier and update it with the following code:
Start the application again if it is not running at the moment with:
Then use postman to test the API
Create some new books:
Get a book using an ID:
And delete a book:
In this tutorial you took a quick look at the fundamentals and basic building blocks of Nest.js and then built a RESTful API.
You will find the complete source code of this tutorial here on GitHub.
Nestjs🐺⚡ | The framework of Nodejs (Part-1) | Controllers, ExceptionFilters, Providers
Nestjs is a server-side framework often confused with the term "Server-Side Angular"
Even though Nest follows the pattern & design principals of Google's Angular but its significantly different than Angular by design
Nestjs is a abstraction layer over traditional nodejs server-side tools & packages
So please don't compare it with http-servers such as: express, koa, fastify, hapi etc.. Nestjs actually uses express & fastify as its platform for http server
Nestjs centralizes all the needed technologies/tools to build perfect, reliable & durable enterprise servers using Nodejs. Its in the league of Django, Spring Boot, Ruby on Rails etc.. server-side frameworks
It follows micro-services architecture but can be used for monolithic servers too
Features of Nestjs: (source: https://docs.nestjs.com)
- Extensible, Reliable, Versatile, Progressive framework
- Offers clean, straight forward & understandable architecture
- Offers out of the box:
- Dependency Injection,
- Routing with decorators using Controllers
- Security with , ,
- Exception filters (unhandled exception layer)
- Separation of logic from controllers using Providers
- Robust Module system
- Lifecycle events & many more
- unit-testing & integration-testing support with &
- It provides/supports (through packages):
- http-server (express/fastify)
- GraphQL server
- websocket server (socket.io/ws)
- database orm (sequelize/mongoose/typeorm/knex/prism)
- request body validation using
- caching using
- task-scheduling using
- task queue using & many more other tools
This is not a complete tutorial. If you want to learn Nestjs completely visit https://docs.nestjs.com. It contains complete details about Nestjs
All of the names & technical terms might feel over whelming but these are pretty easy to implement. Some of 'em take 5-10 lines of code only to implement. But each of them are equally important for a enterprise server or a server with smaller user-base. Nestjs covers the architecture & the dependencies for us
A fact, Nestjs actually helps & guides us as a new backend developer towards all important tools along being used as a tool
Nestjs also has a powerful cli, named . It helps manipulating files/modules. Its kinda like Angluar's CLI but only handles files & modules. It helps you organizing your project more efficiently
I'll be doing a 3 parts of Nestjs tutorial. In part-1 or this part, I'll cover about only , &
But first lets create the project using:
This will create a directory structure of following:
Now lets create a directory inside & inside create 4 files for this tutorial
Controllers are Nest's building block. These are where one will handle incoming request. You can define the route path with http method modifiers (Get, Post, Put, Delete etc..) decorators
Here I'm just creating a Nestjs server instance & adding globally. Pipes are just methods that run before Controllers. Pipes can be used at method/argument level also using decorator. You can even create your own custom Pipes. Also you might've noticed . It's the main point of Nestjs for making all the things work. You'l find more about after Exception Filters section
Now lets create a body validation Schema with & decorators
& will validate a string which is defined & at least has a length of 1 or in other words the string shouldn't be just . Now lets use this one in a request controller:
2. Exception Filters
Exception filters are error handlers that runs when a Controller throws error. It handles that error automatically & sends appropriate, user-friendly error response
If you've followed the code you might've got a hint that Nestjs uses a by default (globally) . The package provides many inherited Exceptions e.g. , , , and many more. You can even create your very own custom
Learn how to create a custom ExceptionFilter
If you want to use a custom exception filter in a route handler, you've to use decorator
Using this long code before every handler/controller can't be hard but if your application has a usecase for using it globally then you just have to use of Nestjs server instance & pass all the global filters as parameters
Providers are another essential part of Nestjs. By far, I was using a temporary variable to store data. That's why such simple thing can be done through Controller handlers. But for bigger, complex logic, it'd be hard to do code separation & reuse. That's where providers comes to play....
You can declare/create a provider using the decorator on top of a class. Then Dependency injection/Logging etc can be done through providers
Here's a provider example. I'm using a custom variable as a database for ease of understanding. But most of the time , , , , etc are provided by the database ORM. So in real-world scenarios these methods aren't needed to be implemented in Providers. Providers should be used for handling more complex logic. But for demonstration lets think these methods as complex logic
Now, lets convert the for using through Dependency Injection. But before we've to put inside the
A module is a class annotated with a decorator. The decorator provides metadata that Nest makes use of to organize the application structure. Each application has at least one module, a root module. The root module is the starting point Nest uses to build the application graph - the internal data structure Nest uses to resolve module and provider relationships and dependencies
That module is the main thing that helps Nest making the dependency graph for Dependency Injection. Example of an :
We've to add every providers ()/controllers that we use inside our controller/provider in a module. Lets put & in :
To let Nest recognize as module, lets add inside the array of :
And this is used as the entrypoint of instance in
Now we can easily use inside or in other Module's controllers/providers
Don't be afraid of Nestjs's Module system. Its hard for the first time but once you get the idea, it all makes sense & this module system is required for Nestjs to do all those cool Dependecy Injection.
BTW, you don't have to add providers/controllers manually in the Module. If you create modules/providers/controller using the nest-cli, it'll be done automatically. Above mentioned Module managing steps can be done automatically just by using these 3 commands
create a module:
create a controller:
create a provider:
Please don't hurt me😶. I know, I should've shown this easier way earlier😁. But that idea of how module works in Nestjs often troubles people to not use Nestjs. So its important to getting the deep insight of it. You can take deep insight of Nestjs Module system here
Here's the complete application
NestJS is an MVC framework for building efficient, scalable Node.js server-side applications.
One of the key benefits of Nest is that it provides an out-of-the-box application architecture that allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications.
What we are building
In this post, I will take you through the journey of getting started with Nest. We will build a Mini Blog that's a Web RESTful API Application.
This simple Mini Blog application will cover:
- Setting up Sequelize and Postgres Database
- Authentication with Passport (Login and Sign up)
- Validating user input
- Route protection with JWT
- Creating, Reading, Updating, and Deleting a blog post
You will need to install Postman, as we will use it to test our API endpoints. And also make sure you have Node.js (>= 8.9.0) installed on your machine. Lastly, you can find a link to the final project GitHub repo here.
Before we get started, we'll discuss some abstractions/concepts that will help you know where to put specific business logic from project to project.
Nest is very similar to Angular – so if you are familiar with Angular concepts it will be straightforward to you.
Still, I'll assume that you have no knowledge of these concepts and will explain them to you.
The controller is responsible for listening to requests that come into your application. It then formulates the responses that go out.
For instance, when you make an API call to the controller will handle this request and return the appropriate response you specified.
Nest allows you to specify your routes as a parameter in the decorator. This helps you group a set of related routes and minimises code repetition. Any request to will be handled by this controller.
At the class methods level, you can specify which method should handle the , , HTTP requests.
In our example, the method with the decorator handles all HTTP requests to get all blog posts. While the method with the decorator will handle a request.
Providers were designed to abstract any form of complexity and logic to a separate class. A provider can be a service, a repository, a factory, or a helper.
A good use case for a service provider is to create a PostService that abstracts all communication to the database into this service. This keeps the nice and clean.
This is just a plain TypeScript class with a decorator (this is how Nest knows it is a provider). is just an interface for type checking.
Here, we are using a simple data structure to store the data. In a real project, this service will be communicating with the database.
The decorator provides metadata that Nest uses to organise the application structure.
Modules are a very important aspect of Nest and each application must provide at least one Module: the application root module. The root module is the starting point Nest uses to build the application graph.
The post service, controller, post entity, and everything related to post should be grouped into a module (PostsModule). Below, we have defined the PostsModule.
Then, we import this module into the root module :
The decorator takes a single object whose properties describes the module:
- Other modules that are needed by this module.
- By default, modules encapsulate providers. It’s impossible to inject providers that are neither directly part of the current module nor are exported from the imported modules. To make the current module providers available to other modules in the application, they have to be exported here. We can also export modules we imported too.
- The set of controllers defined in this module which have to be instantiated.
- in simple terms, all our services and providers within the module will be here.
An interceptor is a specialised set of middleware that lets you peek into the request that goes into the application. You can peek into the request either before it reaches the controller or after the controller is done with the request before it gets to the client-side as a response. You can manipulate the data on their way out in the interceptor.
Guard is also a special kind of middleware that is used mainly for authentication and authorisation. It only returns a boolean value of true or false.
Guards have a single responsibility: they determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time.
A Guard should also implement the interface.
Pipes are also a special kind of middleware that sits between the client and the controller. They are mostly used for validation and transforming data before they get to the controller.
DTO (Data Transfer Object)
Data transfer object is an object that defines how data will be sent over the network. They are also used for validation and type checking.
Install the NestJs CLI. Nest comes with an awesome CLI that makes it easy to scaffold a Nest application with ease. In your terminal or cmd run:
Now you have Nest installed globally in your machine.
On your terminal or cmd, cd into the directory where you want to create your application, and run following commands:
Navigate to on any of your browsers. You should see . Bravo! you have created your first Nest app. Let’s continue.
NOTE: As of this writing, if running throws an error, change your in your to and then delete the re-run .
Your folder structure should look like this:
Sequelize and Database Setup
We’ll start by installing the following dependencies. Make sure your terminal or cmd is currently on your project root directory. Then run the following commands:
Now, create a database module. Run .
Inside the database folder, create an folder, then create a file inside it. This is for the database configuration interface.
Each of the database environments should optionally have the following properties. Copy and paste the following code:
Now, let’s create a database environment configuration. Inside the database folder, create a file. Copy and paste the below code:
The environment will determine which configuration should be used.
On our project root folder, create and files. Copy and paste the following code into both files:
Fill the values with the correct information – only on the file – and make sure it’s added to the file to avoid pushing it online. The is for those who want to download your project and use it so you can push it online.
HINTS:Your username, password, and database name should be what you use to set up your Postgres. Create a Postgres database with your database name.
Nest provides a package out-of-the-box to help load our file. To use it, we first install the required dependency.
Import the into your app root module:
Setting the to will make the properties available throughout the application.
Let’s create a database provider. Inside the database folder, create a file called .
The core directory will contain all our core setups, configuration, shared modules, pipes, guards, and middlewares.
In the file, copy and paste this code:
Here, the application decides what environment we are currently running on and then chooses the environment configuration.
All our models will be added to the function. Currently, there are no models.
Best practice: It is a good idea to keep all string values in a constant file and export it to avoid misspelling those values. You'll also have a single place to change things.
Inside the core folder, create a folder and inside it create an file. Paste the following code:
Let’s add the database provider to our database module. Copy and paste this code:
We exported the database provider to make it accessible to the rest of the application that needs it.
Now, let’s import the database module into our app root module to make it available to all our services.
Setting a global endpoint prefix
We might want all our API endpoints to start with for different versioning. We don't want to have to add this prefix to all our controllers. Fortunately, Nest provides a way to set a global prefix.
In the file, add
Let’s add a User module to handle all user-related operations and to keep tabs on who is creating what post.
This will automatically add this module to our root module .
Generate User Service
This will automatically add this service to the Users module.
Set Up User Database Schema Model
Inside , create a file called then copy and paste this code:
Here, we are specifying what our User table will contain. The provides information about each column in the table. The User table will have and as columns. We imported all the Sequelize decorators from . To read more about Sequelize and TypeScript, check this out.
Let’s create our User DTO (Data Transfer Object) schema. Inside the users folder, create a folder. Then create a file inside it. Paste the following code in:
User Repository provider
Now, create a User Repository provider. Inside the user's folder, create a file. This provider is used to communicate with the database.
Add this to the constants file.
Also, add the user provider to the User module. Notice, we added the UserService to our array. That is because we’ll need it outside of the User Module.
Let’s encapsulate user operations inside the UsersService. Copy and paste the following code:
Here, we injected the user repository to communicate with the DB.
- This method creates a new user into the user table and returns the newly created user object.
- This method is used to look up a user from the user table by email and returns the user.
- This method is used to look up a user from the user table by the user Id and returns the user.
We will use these methods later.
Lastly, let’s add the User model to the file .
Generate Auth Module
This module will handle user authentication (Login and Sign up).
This will automatically add this module to our root module
Generate Auth Service
This will automatically add this service to the Auth module.
Generate Auth Controller
This will automatically add this controller to the Auth module.
Note: is an alias for and is for .
We will be using Passport to handle our authentication. It is straightforward to integrate this library with a Nest application using the @nestjs/passport module.
We will implement two auth strategies for this application:
- Local Passport Strategy: This strategy will be used for logging in users. It will verify if the email/username and password provided by the user is valid or not. If user credentials are valid, it will return a token and user object, if not, it will throw an exception.
- JWT Passport Strategy: This strategy will be used to protect protected resources. Only authenticated users with a valid token will be able to access these resources or endpoints.
Local Passport Strategy
Inside the auth folder create a file and add the following code:
Here, we are importing We extend the to create the In our use case with passport-local, there are no configuration options, so our constructor simply calls without any options object.
We must implement the method. For the local-strategy, Passport expects a method with the following signature: .
Most of the validation work is done in our (with the help of our ), so this method is quite straightforward.
We call the method in the (we are yet to write this method), which checks if the user exists and if the password is correct. returns null if not valid or the user object if valid.
If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the property on the object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our exceptions layer handle it.
Now, add the and to our AuthModule.
Let’s implement the method.
Here, we check if the user exists with the email provided. Then we check if the password in the DB matched what the User provided. If any of these checks fail, we return if not, we return the user object.
This private method compares the user-entered password and user DB password and returns a boolean. If the password matches it returns true. If not, it returns false.
JWT Passport Strategy
Inside the auth folder create a file and add the following code:
Here, we are extending Inside the we added some options object. In our case, these options are:
- supplies the method by which the JWT will be extracted from the . We will use the standard approach of supplying a bearer token in the Authorization header of our API requests.
- : just to be explicit, we choose the default setting, which delegates the responsibility of ensuring that a JWT has not expired to the Passport module. This means that if our route is supplied with an expired JWT, the request will be denied and a response sent. Passport conveniently handles this automatically for us.
- : This is our secret key for the token. This will use the secret key in our file.
- The For the jwt-strategy, Passport first verifies the JWT’s signature and decodes the JSON. It then invokes our method passing the decoded JSON as its single parameter. Based on the way JWT signing works, we're guaranteed that we're receiving a valid token that we have previously signed and issued to a valid user. We confirm if the user exists with the user payload id. If the user exists, we return the user object, and Passport will attach it as a property on the object. If the user doesn’t exist, we throw an Exception.
Now, add the and to the :
We configure the using , passing in a configuration object.
Let’s add other methods we will need to login and create a new user in :
Import and inject JwtService.
- This method is used to login the user. This takes the user information, generates a token with it, and then returns the token and user object.
- This method is used to create a new user. This takes the user information, hash the user password, saves the user to the DB, removes the password from the newly returned user, generates a token with the user object, and then returns the token and user object.
- This private method generates a token and then returns it.
- This private method hashes the user password and returns the hashed password.
We will be using all these functions later.
Now, let’s create our and methods:
When we hit this endpoint POST will call . This will take the user email/username and password, then run the validate method on our local strategy class. The will generate a JWT token and return it.
The POST endpoint will call the method, create the user, and return a JWT token.
Let’s try it out…
Open your Postman application and make sure it's running. Send a POST request to and input your body data to create a user. You should get a token and the user object returned.
Now that we have a user, let’s log the user in. Send a POST request to and input just your username and password. You should get a token and the user object returned.
Notice how we are not validating any of the user's input. Now, let’s add validation to our application.
Inside the core folder, create a pipes folder and then create file. Copy and paste the following code:
Let’s auto-validate all our endpoints with by binding at the application level. Inside the file, add this:
Now, let’s update our users file:
Here, we are importing these decorators from
- ensures the field isn’t empty.
- checks if the email entered is a valid email address.
- ensures the password character is not less than six.
- ensures only the specified value is allowed (in this case, male and female).
class-validator has tons of validation decorators – check them out.
Let’s try our validation out…
Without passing any value, I got the following validation error. Our validation is working now. This validation is automatic to all endpoints with a dto (data transfer object).
Unique User account
Let’s add a guard that prevents users from signing up with the same email twice since email is unique at the schema level.
Inside the core folder, create a guards folder, then create a file. Copy and paste the following code:
Now, let’s add this guard to our signup method in :
Let’s try to create a user with an email that already exists in our database:
This will automatically add this module to our root module .
Generate Post Service
This will automatically add this service to the Post module.
Generate Post Controller
This will automatically add this controller to the Post module.
Create a file inside the posts folder. Copy and paste the following code:
The only new thing here is the specifying that the userId column is the id of the User table and specifying the relationship between the Post table and User table.
Post DTO (Data Transfer Object)
Inside the posts folder, create a folder then create a file inside it. Copy and paste the following code:
Here, our post body object must have a title, and body and title length must not be less than 4.
Create a file inside the posts folder. Copy and paste the following code:
Add this to the constants file.
Add our Post provider to our Post Module file:
Now, add our Post entity to our database provider. Import the Post entity inside the file, add the Post to this method:
Post Service Methods
Copy and paste the following inside the Post service file:
Here, we are injecting our Post repository to communicate with our database.
- This accepts post object and the id of the user creating the post. It adds the post to the database and returns the newly created Post. The is for validation.
- This gets all the posts from the database and also includes/eager load the user who created it while excluding the user password.
- This finds and returns the post with the id. It also includes/eager load the user who created it while excluding the user password.
- This deletes the post from the database with the id and userId. Only the user who created the post can delete it. This returns the number of rows that were affected.
- This updates an existing post where is the id of the post, is the data to update, is the id of the original creator. This returns the number of rows that were updated and the newly updated object.
Post Controller Methods
Copy and paste the following inside the Post controller file:
Most of the CRUD operation functionality is done in our
- This handles request to endpoint. It returns all the posts in our database.
- This handles request to endpoint to get a single post, where 1 is the id of the post. This throws a 404 error if it doesn’t find the post and returns the post object if it does find the post.
- This handles request to endpoint to create a new post.
- is used to protect the route (remember our JWT strategy). Only logged in users can create a post.
- This handles the request to endpoint to update an existing post. It is also a protected route. If the is zero that means no post with the params id was found.
- This handles the request to delete an existing post.
Let’s try our CRUD operation out…
Create a Post
Log in and add your token since creating a post route is a protected route.
Read a single Post
This route isn’t protected, so it can be accessed without the token.
Reading all Posts
This route isn’t protected, so it can be accessed without the token too.
Updating a Single Post
This route is protected, so we need a token and only the creator can update it.
Deleting a Post
This route is protected, so we need a token and only the creator can delete it.
Nest.js gives you a more structured way of building your server-side applications with Node.
For more information, check out the official NestJS website here.
Finally, I hope this article was useful to you! The link to the final project GitHub repo is here.
You can connect with me on LinkedIn and Twitter.
If you read this far, tweet to the author to show them you care. Tweet a thanks
Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started
Modern Full-Stack Development with Nest.js, React, TypeScript, and MongoDB: Part 1
Basic knowledge and previous experience with building web applications with React will help you to get the best out of this series. Although not mandatory, you should know a few things about TypeScript. And to make it easy for everyone to follow along, I will endeavor to break down any complex implementation. Furthermore, you will also need to ensure that you have Node.js and Yarn package manager installed in your development machine. If you are yet to get them installed, kindly follow the instructions here to learn how to install Node.js properly and here for Yarn package manager.
Also, you need to have MongoDB installed on your machine. Follow the instructions here to download and install it for your choice of the operating system. To successfully install MongoDB, you can either install it by using Homebrew on Mac or by downloading it from the MongoDB website.
This tutorial uses a macOS machine for development. If you’re using another operating system, you may need to use for commands in the first steps.
As pointed out earlier, in this tutorial, we will combine these awesome contemporary web tools and build an application with it. At the end of the article, you would have gathered enough knowledge for you to explore the benefits of building applications by combining React and TypeScript in either a new project or to enhance your existing projects.
Why Build React Applications with TypeScript
As you may be aware, React is a component-based frontend framework and make use of props and state objects here and there. Building React applications with TypeScript allows you to have strongly-typed components that have well defined and identifiable props and state objects. This will ensure that the usages of your components are type-checked by the compiler, and you can spot errors on time.
This will, in a nutshell, make you more productive as a developer and make your code easier to read and understand.
"React is a component-based frontend framework."
What You Will Build
You are going to build a blog application with which users can:
- Create and save a new post.
- View the newly saved post and all other created posts on the homepage.
- Carry out processes such as editing and deleting posts.
Also, to persist data into the database, you will make use of MongoDB. Here is a preview of what to expect at the end of this tutorial:
This application will allow users to create a blog post only if they have been authenticated and authorized. Otherwise, they will only be able to view the created posts by authenticated users. Authentication and authorization of users will be handled by Auth0.
You will start gradually and take things one step at a time, starting by building the complete backend API and allow any user to have access and make successful API calls to create, retrieve, and edit data in the database. Then you will proceed to secure the API by managing user authentication via Auth0. To test all the implementation in this part of the series, you will use Postman.
Building Backend APIs with Nest.js
As mentioned, the backend API will be built using Nest.js. Here, you will start by installing and configuring Nest.js and then proceed to flesh out the structure necessary for the API.
Installing and configuring Nest.js
You can easily install a new Nest.js project using the command-line interface built specifically for scaffolding Nest applications called Nest CLI.
You will start by using the command-line interface built specifically for scaffolding a new Nest.js application to create yours. Alternatively, you can clone the starter project for Nest.js here on GitHub. Even though both approaches will produce the same outcome, for the sake of this tutorial and as it recommended for a first time user by the Nest.js team, you will use the Nest CLI to create your project.
Install the CLI by running the following command:
Once the process is complete, confirm if Nest CLI has been installed by running the following command:
You will see an output similar to the following indicating the version installed on your machine:
💡 Please note that this version might be different from yours.
Craft a new project for this tutorial by using the command as shown here:
Immediately after running the preceding command, will prompt you to choose a package manager you would like to use. Select and hit on your computer to start installing Nest.js:
This will create a new Nest.js project in a directory within your local development folder. Now, move into the newly created directory and run a command to install other required server dependencies:
Because Nest.js supports integrating with MongoDB database by using Mongoose, what you have done here is to install and the dedicated package created by Nest.js team for the integration named .
Once the installation process is complete, you can then easily import the into your application. More about this later in the tutorial.
Next, before you start the application, open the project using your code editor, and edit the default port as shown below:
What you have done here is to change the default port of Nest.js to to avoid port conflict with the React application, which you will build in the next part of this series. That will run on port by default.
With that done, start the application using the following command:
This will run the application on port on your local machine. Navigate to http://localhost:5000 from your browser of choice, and you will see your application running.
In this section, you have successfully installed the Nest CLI and leveraged it to generate the project for this tutorial. You then proceeded to run the application on the default port . Next, you will work on ensuring a successful connection between your app and its database that will be created.
Configuring a database connection
In this section, you will start by setting up the configuration necessary for database connection, which includes configuring and integrating MongoDB into your application. As instructed in the prerequisites section of this tutorial, you should have MongoDB installed by now. If this is your first time installing it, you should have it running automatically at the moment and might not be necessary to start it. To check if MongoDB is currently running, open a different terminal window to keep the backend application running and run the following command :
If an output similar to the one below is displayed in your terminal, then MongoDB is running:
Otherwise, execute the following command to start MongoDB:
Note: MongoDB usually stores data in within the root directory of your computer’s operating system, but If your operating system is macOS Catalina or ran into an error while running the command above, the root folder is not writable. To handle this, you will have to create a different directory in another location and reference that path when running the command, as shown here:
This will start the MongoDB service and run the database in the background while waiting for connections from your application.
Next, open this file and update its content, as shown here:
Here, you imported the into the root and then used the method to supply the connection to the database. Once the editing of the above file is completed, you have now successfully set up a database connection for your application by using the Mongoose module for MongoDB.
Setting up a database schema and interface
Here, you will define the structure and datatype of the data in your application by creating a TypeScript interface, which will be used for type-checking and to define the types of data that should be passed into the application. Also, you will create a database schema, as Mongoose tends to derive everything from a Schema defined within a particular application.
To begin, go back to the terminal where the application is currently running and stop the process with , then navigate back into the directory and create a directory named within it. Now create a sub-directory named within the initially created directory.
This new directory will house all the database schema that will be required by your application. Now, create a schema file and called it and save it within the folder. Open this file and add the following content within it:
This definition specifies that all fields will store and only accept string values. With this in place, the datatype of data that will be stored in the database will be properly controlled.
Next, you will create the interface majorly for type-checking. To begin, create a new directory named within the folder. And within it, create a file and name it and add the following code to it:
Here you have successfully defined the types of data for a type as string values.
Creating a Data Transfer Object (DTO)
A data transfer object will help define how data will be sent over the network and control how data will be posted from the application to the database. To achieve this, create a directory inside the folder. Within the newly created folder, create a new file and name it . Paste the following code into it:
From the preceding code snippet, you have marked each of the individual properties in the class to have a data type of and as to avoid unnecessary mutation.
Creating the blog module
Module in Nest.js is a class annotated with a decorator. It helps to keep the application structure organized. It is recommended by Nest.js that each application should have at least one module, mostly the root module. In view of that, you will use the command to generate a module for your application. To do that, ensure that you are still within the directory and execute the following command:
The command above will generate a new module named for the application and update the root module for it by automatically importing the newly created . With this in place, Nest.js will be aware of another module within the application besides the root module. The generated blog module file will look like this:
You will update this with the required contents later in the tutorial.
Creating Nest.js services and controllers
Here you will generate a service, also known as a provider, and afterward, you will create a controller to handle all HTTP requests from the application. Services in Nest.js are meant only to handle any complex business logic for a specific purpose and return the appropriate response to the controller.
Run the following command while you are still within the project directory to generate a new service file:
The thing to note here is that the command above will create a file, which you can use for testing. It has also created a new file, which will hold all the logic for this application and then communicate with the MongoDB database by adding and retrieving data from it. Lastly, it has also automatically imported the newly created service and added it to the .
Open the newly created and replace its default contents with the following code with methods for creating a post, retrieving all created posts, and fetching the details of a single post from the database:
In this file, you first imported the required module from , , and . You also imported an interface named and a data transfer object . In the , you added , which will inject the model into this class. With that, you will now be able to use this injected model to retrieve all posts, fetch a single post, and carry out other database-related activities.
Next, you created , and methods to add a new post, retrieve a single post and fetch all posts from the database respectively.
Lastly, within this file, to enable editing and deleting any created post, you need to add the following immediately after the method, as shown here:
All the methods created above will help facilitate proper interaction with the MongoDB database from the backend API. You can now proceed to create the required routes that will handle HTTP calls from a front-end client.
Create a new controller
Controllers in Nest.js are meant to receive incoming HTTP requests from an application frontend and return an appropriate response. This will ensure that the controller is not bloated as most of the business logic has been abstracted to a service.
You have created the service earlier, so here, you will leverage the command to generate a new controller file by running the following command, while you are still within the project directory:
The preceding command created two new files within the directory, , and . You can ignore the former file for now, as you won’t be writing any tests in this tutorial. The latter file is the controller itself and it is a TypeScript file decorated with metadata, as it is obtainable for every controller created in Nest.js. Now, open the file with your text editor and update its content with the following:
From the code snippet above, you imported all the necessary modules to handle HTTP requests from module. You then proceeded to import three new modules, which are: , , and . You will create the module in the next section.
To have access to all the functions declared within the earlier, you injected it into the controller via a constructor. This is a pattern regarded as dependency injection used in Nest.js to increase efficiency and enhance the modularity of the application. Finally, you created the following asynchronous methods:
- : This method will carry out the functionality of receiving an HTTP GET request from the client to fetch all posts from the database and then return the appropriate response. It is decorated with a .
- : This takes a as a parameter and fetches a single post from the database. In addition to the parameter passed to this method, you realized the addition of an extra method named . This method implements the interface from Nest.js. Its purpose is to validate and ensure that the parameter can be found in the database. You will define this method in the next section.
- : This method will handle a POST HTTP request to add a new post to the database.
For editing and deleting a particular post, add two more methods to the file. To accomplish that, paste the and methods directly after the method that you previously added in the same file:
Here you have added:
- : This method accepts a query parameter of and will carry out the functionality of updating a single post. It also made use of the method to provide proper validation for the post that you need to edit.
- : This method will accept a query parameter of and will delete a particular post from the database.
Similarly to the , each of the asynchronous methods you have defined here has a metadata decorator and takes in a prefix that Nest.js uses as a routing mechanism. It controls which controller receives which requests and points to the methods that should process the request and return a response, respectively.
For example, the that you have created in this section has a prefix of and a method named that takes in a prefix of . This means that any GET request sent to an endpoint of () will be handled by the method. This example is similar to how other methods will handle HTTP requests.
Validation for Mongoose with Pipes
Navigate to the directory and create a new folder named . Now create another folder within the newly created folder and name it . Then finally, create a new file within the newly created folder and name it . Open this file and add the following content to define the accepted data:
The class implements the method from the module. It has a single method named that takes in value as a parameter — in this case. With the method above, any HTTP request from the frontend of this application with a that can’t be found in the database will be regarded as invalid.
After creating both the service and controller, you need to set up the model that is based on the . This configuration could be set up within the root , but in this instance building, the model in will maintain your application’s organization. Open the and update it as shown here:
This module uses the method to define which models should be registered in the module. Without this, injecting the within the using decorator wouldn’t work.
Test without authentication
Go back to the terminal and test the application by running the following command from the terminal while you are still within the project’s directory:
The preceding command will run the application in watch mode to track any new changes while the application is still running.
Note: Ensure that the MongoDB instance is still running from the other terminal as mentioned earlier. Otherwise, open another terminal and run to start the MongoDB process in the background. You can use Postman to test the API. Postman is a testing tool to confirm and check the behavior of your web service before deploying to production.
Create a post using the application
As shown here, a POST HTTP call was made to http://localhost:5000/blog/post endpoint with the details of a blog post. After a successful process, the created post was returned as a response with a message indicating that it was created successfully.
From the screenshots above, it is obvious that all the implemented logic for your backend API is working properly, but this raises another concern. Any random user can easily make an API call to retrieve or create a new post without authentication and succeed. This is not acceptable as the applications need to be smart enough to manage the identity of users.
To make the API protected, first, you will need an Auth0 account, create a new account if you don’t have one already.
Try out the most powerful authentication platform for free.Get started →
Securing Nest.js with Auth0 and managing the identity of users
After creating an account, log in to it and head over to the API section of your Auth0 management dashboard and select APIs from the side menu. This will show you your list of APIs if you have created any for your account, but for this tutorial, go ahead and click on the CREATE API button and set up a new one. Next, provide a friendly name as you deem fit for your API. Set the identifier as . This will be used as the audience later when configuring the access token. Once you are done, leave the signing algorithm as , as it is the best option from the security point of view, and click on the CREATE button to proceed:
Immediately when you created this API, Auth0 also automatically created a test application for you to use. This is a machine-to-machine application that you will only use here for testing purposes for this part of the tutorial. You will create a new single-page application that will represent the front-end React app in the next part of the tutorial.
Next, click on "Applications" from the side menu to view the list of applications for your account and select the test application that was generated. You will then click on the "Settings" tab.
Now locate the Allowed Callback URLs fields and add as the value. This will be useful in the next part of this series. You can now save the changes to proceed. Don’t forget to copy the , , and as you will need it soon to configure your API.
Defining a Nest.js authentication middleware
To protect your routes and ensure that every user gets authenticated before accessing some of the resources provided by your API, you will make use of Auth0.
How this will work is that once a user is authenticated by Auth0, an access token will be generated for such user to make API calls subsequently. To verify the generated JWT token issued by Auth0, you will make use of Express middleware provided by .
Stop the application if running and install the following libraries:
Included in the libraries above is a module to load variables from a file.
To easily access and reference credentials such as the for your application on Auth0, create a within the root of your application and paste the following content:
Replace the with the appropriate credential as obtained from your Auth0 dashboard.
To configure the authentication middleware that will ensure that every call to your protected endpoint is identified by an access token, create a folder named within the directory. Then create a new file named in it. Paste the following in the newly created file:
This code will check if the Access Token included in a request is valid. If the token is not valid, the user will get a message indicating that the authorization token is not valid.
After this, navigate back to the file and update the file as shown here:
With this implementation, any subsequent requests without an Access Token to the following routes will not be allowed by the application:
To test this out, start the application and the MongoDB instance again using and respectively. Then try to send a request to from Postman. You will see the response as depicted by the image below:
In the next part of this series, you will have the opportunity to generate an access token on the fly once authenticated by Auth0. But as a proof of concept, for now, you can obtain a test access token for your API from the Auth0 account management dashboard. Access the API section in your Auth0 dashboard and click on the API that was created earlier.
Now click on the tab and scroll down to copy the Access Token shown under the Response subtitle.
Next, open up Postman and from the Authorization tab, select and paste your Access Token:
Test all endpoints using Postman
Now, you can try to access all the protected endpoints:
In this tutorial, you were able to successfully build an API using Nest.js and then persist data into your database using MongoDB. You went further to protect some of the endpoints with the application by ensuring and verifying the JWT (JSON Web Token) issued by Auth0.
This is the first part of this series, and from the second part, you will set up a user interface and create frontend logic using React and TypeScript.
The Auth0 Identity Platform, a product unit within Okta, takes a modern approach to identity and enables organizations to provide secure access to any application, for any user. Auth0 is a highly customizable platform that is as simple as development teams want, and as flexible as they need. Safeguarding billions of login transactions each month, Auth0 delivers convenience, privacy, and security so customers can focus on innovation. For more information, visit https://auth0.com.
Js tutorial nest
Developing a Secure API with NestJS: Getting Started
We tested this tutorial using NestJS , Node.js , and npm .
NestJS is known as an architecture framework for Node.js, but what is an "architecture framework"? Is this yet another buzzword? Nope! It's legit.
NestJS may feel like the Laravel or Rails of the Node.js world as it favors convention over configuration. It offers you opinionated guidelines and code conventions. So, instead of worrying about naming or organizing files and folders, you can focus on building features for your product.
On its mission to remove the guesswork out of API development, NestJS offers first-class support for TypeScript to add static type-checking to your projects. Your API code becomes self-documented: you'll know if a method expects a , a , a , or a .
Today, you'll learn how to build a secure API with NestJS and create your own opinion on the framework.
What You Will Build
Your goal is to create and secure a feature-complete API, which lets clients perform data operations on a mock restaurant menu. To test, consume, and even try to hack your API, you'll use a demo client called "WHATABYTE Dashboard".
This dashboard is inspired by the sleek web player from Spotify.
We tested this tutorial using Node.js and NPM . If you need to install any of them, follow the instructions provided by the Node.js Foundation for your operating system.
For simplicity, you'll store data in-memory and not in an external database.
For security, you'll limit API access by following these business rules:
Anyone can read data.
Only users with a role are authorized to write data: create, update, or delete menu items.
Get Started with NestJS
NestJS offers a powerful CLI tool to build your application. To generate a new project, use to run the NestJS CLI without installing it globally in your system:
The command is available with and higher.
The CLI asks you to choose a package manager, or , and proceeds to install project dependencies using your selection. To follow this tutorial, choose .
Once the installation is complete, you get a directory called . Navigate to this directory:
Clean Up the NestJS Starter
For simplicity, you won't be writing any tests in this tutorial. However, it would be best if you wrote robust tests for any production-ready application. As such, delete the directory and the file from your project:
Refer to the NestJS Testing documentation for details on how to perform automated tests.
After that, delete the files defining and :
Deleting these files breaks as it depends on and . To fix that, open the project in your preferred IDE and update as follows:
Use Environmental Variables
is the entry point of your application. However, this file uses a hard-coded port number to listen for incoming requests, , making your application less adaptable to different development and production environments.
To fix that, you can store environmental variables locally in a file and use a package like to load them into the global variable .
To start, install in your project:
Then, create this hidden file under the root project directory:
Open and populate it with the following data:
To attach data from into , you need to call the method at the top of each module that needs that data. As such, update to replace the hard-coded port number with as follows:
Now when your application runs, it listens for requests on whatever the value of may be — in this case.
⚠️ Caution: may eventually contain sensitive information, such as API keys or secrets. Add it to before committing code to version control.
Next Step: I am ready to start building my NestJS app
I ran into an issue
"@nestframework is an architecture framework for @nodejs. Learn how to create scalable and maintainable server-side apps with it."
The feeling from a very acute one turned into a simple pleasant memory. I told myself in every possible way that it was not good to love a married man who is much older than me. I met with peers, kissed, went to the movies. But when in the evening in the bathroom I caressed myself under streams of warm water, I imagined him.
You will also like:
- Fender wildwood
- Trailer cord
- Wood flower diffuser
- Golf wang symbol
- Fairfax chevrolet dealers
- Prototype knuckles
An hour passed, another went, I got excited, and then I was overwhelmed: "he fucked someone, and that's why he's sleeping. " I undressed, turned on the light and sat. Naked on the bed, she continued, and the memory suddenly became vivid and clear, as it was yesterday. Wake up dear, you forgot to caress me trying to hide your irritation, she said, shaking his shoulder.
What the hell, Light.