Express.js is a great technology for building secure and robust REST APIs, however, it doesn’t provide a predefined structure. Its minimalistic nature allows you to handle essential aspects like routing, code organization, and security measures either manually or by leveraging available middleware and libraries.
In contrast, Nest.js, built on top of Express.js and Node.js, introduces a higher-level abstraction that offers a clear structure, a robust code organization approach, and simplified implementation details. Essentially, Nest.js provides a more structured architecture for building efficient and secure backend APIs and services.

Setting Up a Nest.js Project
To get started, you first need to install Nest.js' command line (CLI) globally by running the command below:
Once the installation is complete, go ahead, and create a new project, by running:
Next, Nest.js CLI will prompt you to choose a package manager to install the dependencies. For this tutorial, we’ll usenpm, the Node Package Manager. Selectnpmand wait while the CLI creates a basic Nest.js project and installs all the required configuration files and initial dependencies required to run the application.
After the project is set up, navigate to the project directory and start the development server.
Finally, run the command below to install the packages we’ll use for this project.
You can find this project’s code in thisGitHub repository.
Configure MongoDB Database Connection
Set up a MongoDB database locallyorconfigure a MongoDB cluster on the cloud. After setting up the database, copy the database connection URI string, create a.envfile in the root directory of our project folder, and paste in the connection string:
Next, update theapp.module.tsin thesrcdirectory file to configure Mongoose as follows:
The provided code configures three essential modules for the Nest.js application:ConfigModulefor environment configuration,MongooseModulefor establishing the MongoDB connection, andUserAuthModulefor user authentication. Please note that, at this stage, an error might occur since theUserAuthModuleis not yet defined, but we’ll create it in the next section.
Creating the User Authentication Module
To maintain clean and well-organized code, create a user authentication module by running the following command.
The Nest.js CLI tool automatically generates the required module files. Additionally, it will update theapp.module.tsfile, incorporating the necessary changes related to the user authentication module.
You can opt to create the main project configuration files manually, nonetheless, the CLI tool simplifies this process by automatically creating the required items, in addition to, updating the changes accordingly in theapp.module.tsfile.
Create a User Schema
Inside the newly createduser-authfolder in thesrcdirectory, create a newschemas/user-auth.schema.tsfile, and add the following code to create a Mongoose schema for theUsermodel
Creating the User Authentication Service
Now, let’s create the user authentication service that will manage the authentication logic for the REST API by running the command below:
This command will create auser-auth.service.tsfile inside the user-auth directory. Open this file and update it with the following code.
TheUserAuthServiceclass implements the logic of user registration, login, and retrieving user data. It uses theuserModelto interact with the database and perform the required actions including hashing the password during registration, validating login credentials, and lastly, generating JWT tokens after successful authentication.
Implementing the Authentication Guard
To ensure the security of sensitive resources, it is crucial to limit access exclusively to authorized users. This is achieved by enforcing a security measure that mandates the presence of a valid JWT in subsequent API requests made to protected endpoints, in this case, theusersroute. In theuser-authdirectory, create a newauth.guard.tsfile and add the code below.
The code implements aguard,as specified in the official documentation, to protect routes and ensure that only authenticated users with a valid JWT token can access them.
It extracts the JWT token from the request header, verifies its authenticity using theJwtService,and assigns the decoded payload to therequest[‘user’]property for further processing. If the token is missing or invalid, it throws anUnauthorizedExceptionto prevent access to the protected route.
Now, createconfig.tsfile in the same directory, and add the code below.
This secret key is used to sign and verify the authenticity of JWTs. It’s essential to store the key value securely to prevent unauthorized access and protect the integrity of the JWTs.
Define the API Controller
Create a controller that handles the API endpoints for user authentication.
Next, copy the code provided in thisGitHub repository file, and add it to theuser-auth.controller.tsfile—it defines the endpoints for user registration, login, and retrieving user data. TheUseGuards(AuthGuard)decorator is included to enforce authentication for thegetUsersendpoint, ensuring that only authenticated users are granted access.
Update the user-auth.module.ts File
To reflect the changes made to the project, update theuser-auth.module.tsfile to configure the necessary modules, services, and controllers for user authentication.
Finally, spin up the development server and test the API endpoints using Postman.
Building Secure Nest.js REST APIs
Building secure Nest.js REST APIs requires a comprehensive approach that goes beyond just relying on JWTs for authentication and authorization. While JWTs are important, it is equally crucial to implement additional security measures.
Additionally, by prioritizing security at every stage of API development, you may ensure the security of your backend systems.