Nestjs is a cutting-edge Node.js framework for developing server-side applications that are efficient, dependable, and scalable. It is simple to integrate with NoSQL and SQL databases such as MongoDB, Yugabyte, SQLite, Postgres, MySQL, and others. It supports popular object-relational mappers such as TypeORM Sequelize and Mongoose.
In this tutorial, we'll create an e-commerce application with SQLite and TypeORM. We'll also look at Arctype, a powerful SQL client and database management tool.
Let's get started!
Prerequisites
This tutorial is a hands-on demonstration to get you started. Ensure you've met the following requirements:
You have Node (>= 10.13.0, except for v13) installed
You have a foundational knowledge of Javascript
Arctype installed
Project Setup
To get started with Nestjs, install the Nestjs CLI with the command below:
Once the installation is completed, create a Nestjs project with the command below:
Choose your npm as the package manager, hit the enter button, and wait for Nest to install the required packages to run this application.
Once the installation is completed, change the directory to the project folder with the command below:
Then open the project directory in your favorite text editor or IDE, open a new terminal, and run the server on development mode (This will enable hot reload and allows us to see possible errors on the console) with the command below:
Install Dependencies
With the server up and running, open a new terminal window so you don't quit the server. This will allow you to see the effect of the changes made to the codebase throughout this tutorial.
Then install the dev dependencies with the command below:
You can grab a cup of coffee while the npm installs the packages. Once the installation is completed, let's get our hands dirty.
Create App Modules
With all the necessary packages required to run the application, let's proceed to create the application modules. To build a clean and easily-maintained application, you'll generate separate modules for all the features implemented in this application. Since this is an eCommerce application, you'll have authentication, cart, products, and orders. All these will be in their own separate modules. Let's start with the authentication module.
Create Authentication Module
Generate an authentication module with the command below:
The above command creates an auth folder in the project's src directory with the necessary boilerplates and registers the module in the project root module (app.module.ts file).
Next, create a product, cart, order, module with the command below:
The above will create a product, cart, and order folder in the project's src folder with the basic boilerplates and register these modules in the project's root app module.
Setting up TypeORM and SQLite Databases
With the app modules installed, set up TypeORM to connect your application to SQLite Database and create your module entities. To get started, open the app.module.ts and configure your SQLite database with the code snippets below:
In the above code snippet, you connected the application to an SQLite database using the TypeORM forRoot, specifying the database type, database name, and the location where Nestjs can find the model entities.
Once the server refreshes, you should see a shoppingDB file created in the root directory of this project.
Create App Entity Models
With the database setup, let's create the entity models for our app modules. We'll start with the auth module. Generate an entity file in the auth module folder with the command below:
Then add the code snippet below to define the user table properties:
In the code snippet, you imported the decorators required to set up your database table. You also imported the cartEntity and orderEntity class which you'll create shortly. Using the typeorm decorator, we defined the database properties of the user's model. Finally, we created one-to-one and one-to-many relationships between the users entity and the cartEntity and orderEntity. This way, you can associate a cart item with a user. The same applies to the user's order.
Next, create the product entity class with the command below:
The above command will generate a product.entity.ts file in the products module folder.
Now configure the product table properties with the code snippet below:
In the above code snippet, we configured the properties of the product table and created a one-to-many relationship with the cart entity.
Then create the cart entity with the command below:
The above command will generate a cart.entity.ts file in the cart module folder. Now add the code snippet below to the file you created to configure the cart table properties.
In the above code snippet, you configured the properties of the cart table, created a many-to-one relationship between the cart entity and a many-to-one relationship with the users entity.
Lastly, create the order entity with the command below:
The above command will generate an order.entity.ts file in the order module folder. Open the order.entity.ts and configure the database table with the command below:
In the above code snippet, you created a one-to-one relationship between the users entity and a one-to-many relationship with the product entity.
At this point, your database entities are set and connected. Now create your business logic to store records on these entities.
Create App Services
Now create the services for the modules in this application. Here you'll allow the admin to add products to the product table, authenticate users, allow users to add the products in the store to the cart, and order the product via their cart.
Create the Auth Service
To create the auth service, run the command below to generate the service for the auth module.
The above command will generate an auth.service.ts file in the src/auth/service folder. Now open the auth.service.ts file and add the code snippet below:
In the above code snippet, you imported InjectRepository,Repository decorator, JwtService, and bcrypt modules. Then, using the InjectRepository decorator, you made the User entity class available in the auth service, providing the method to perform CRUD operations in your User entity.
Then create a signup method to allow users to register in the application with the code snippet below:
Now create the validateUser method to validate the users' details and the login method to generate a jwt token for the authenticated user.
Now we can implement our Passport local authentication strategy. Create a file called local.strategy.ts in the auth module folder, and add the following code:
In the above code snippet, you've implemented a passport-local strategy. There are no configuration options, so our constructor simply calls super() without an options object.
You've also implemented the validate() method. Passport will call the verify function for each strategy using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a validate() method with the following signature: validate(username: string, password:string): any.
Then create a jwt-auth.guard.ts file in the auth module folder and define a custom auth guard with the code snippet below:
Then configure the JWT module in the auth.module.ts file in the auth module folder. Before that, create a constants.ts file in the same auth module folder to define a JWT secret with the code snippet below:
You can generate a more secured JWT secret on production, but we'll use the one for demonstration sake.
Now import all the required modules in your auth.module.ts file with the code snippet below:
Then in the array of imports, configure JWT with the code snippet below:
In the above code snippet, we add the PassModule package to allow Passport to handle the users' authentication and configured JWT using the JwtModuleregister method. We pass in the secret we created in the constants file and specify the generated token's expiration time (You can reduce or increase the time depending on the use case).
Create the Product Service
With the auth service setup, generate a product service with the command below:
Now open the product.service.ts file generated by the above command in the product module and add the code snippets below:
In the above snippet, we created our CRUD services. The create, update, and delete methods are restricted from the users. Only the admin can create a product, delete or update a product.
Now open the product.module.ts file and make the product entity accessible with the code snippet below:
Create the Cart Service
At this point, the admin can add products to the database, and authenticated users can see all available products. Now let's allow the users to add the items they like to the cart. To get started, generate a Cart service with the command below:
Then open the cart.service.ts file generated by the command and add the code snippet below:
You imported the modules required to create a Nest.js service in the above code snippet. We also imported them here since you created a relationship between the cart, user, and product entities. Then, you make a constructor method to bind these entities to the CartService class. Now create a method to add an item to the cart.
In the above code snippet, you created an addToCart method that takes the productId, quantity, and user as arguments. Then check if the user has the item already in their cart. If so, you increment the quantity and update the total price of that item. Else, you add the item to the user's cart.
Next, make the cartEntity, productEntityUser entity, and the productService accessible in the cartService by registering them in the cart.module.ts file with the code snippet below:
Lastly, create a getItemsInCart method that takes a user as an argument to return all the carts belonging to a particular user.
Create the Order Service
When users are done shopping, they can order the items in their cart. Generate an order service with the command below:
Now open the order.service.ts file generated from running the above command and add the code snippet below:
You imported the modules required to create a Nest.js service in the above code snippet. We also imported them here since you created a relationship between the cart, user, and product entities. Then, you created a constructor method to bind these entities to the OrderService class. Now create a method to order the items in the user's cart.
Then create another method to get a user's order from the array of orders from the database with the code snippet below:
Lastly, open the order.module.ts file and make the users, product, and cart entities accessible in the orderService with the code snippet below:
Create App Controllers
With the application services successfully created, let's create the API routes for the app services.
Create the Auth Controller
Generate an auth controller with the command below:
Now open the auth.controller.ts file generated from running the above command and configure the auth routes with the code snippet below:
Create the Product Controller
With the auth controller routes configured, generate a product controller with the command below:
Open the product.controller.ts file generated from running the above command and configure the product routes with the code snippet below:
In the above code snippet, you defined the CRUD routes for the product service. We used the UseGuard decorator passing your JwtAuthGaurd to protect the routes from unauthorized users.
Create the Cart Controller
Now generate a cart controller with the command below:
Then open the cart.controller.ts file generated from running the above command and configure the cart routes with the code snippet below:
Create the Order Controller
With the cart routes configured, create an order controller with the command below:
Then open the order.controlle.ts file generated from running the above command and configure the cart routes with the code snippet below:
At this point, all your API routes have been configured.
Test Application
Now let's test them out using Postman. The results of come tests are shown below.
Feel free to test the other routes and play around with the code here on Github.
Connecting Arctype to SQLite Database
Arctype is an SQL client and database management tool that's fun to use. It allows you to have a visual representation of your database tables, and you can perform the CRUD operations directory in your database using Arctype. Connecting Arctype to an SQLite database is a straightforward process. To get started, follow the steps below:
First, launch Arctype. You'll see a screen like the one below, allowing you to add your credentials.
Click on the SQLite tab. This will bring up the screen below.
Click on the Choose SQLite File button and navigate to your project folder. Select the application database file and press the open button. Press the save button, and you should see your database entities, as shown in the screenshot below.
Conclusion
By building a demo project, we've learned how to make an e-commerce application using Nestjs and SQLite database. First, we started with the introduction of NestJS. Then, we created a NestJS application, connected the application to an SQLite database using TypeORM, and performed CRUD operations. Now that you've gotten the knowledge you seek feel free to add extra functionality to the application.
Comments