NestJs Ecommerce Development — Part I
In this tutorial series we will use NestJs to develop a simple Ecommerce backend. The database used is MongoDB.
Start with NestJs cli to create a new app —
nest new nestjs-ecommerce
Add Mongoose —
npm install --save mongoose
Next add mongoose module in AppModule imports section —
MongooseModule.forRoot(‘mongodb://localhost/nestjs-ecommerce’
Our next step is to create Category module —
Create module using- 'nest g module category'category — dtos — schemascategory.controller.tscategory.service.tscategory.module.ts
Category model will have unique slug. So using plugin mongoose-slug-generator. Category schemas folder has schema for Category —
import { Prop, Schema, SchemaFactory } from ‘@nestjs/mongoose’;import { Document } from ‘mongoose’;export type CategoryDocument = Category & Document;@Schema()export class Category {@Prop({ required: true })name: string;@Prop({ slug: 'name', unique: true }) // The slug: 'name' will //create unique slugs on name property.slug: string;@Prop()banner: string;}export const CategorySchema = SchemaFactory.createForClass(Category);
To activate plugin with mongoose feature module category we have to add the below lines in CategoryModule imports section.
MongooseModule.forFeatureAsync([{name: Category.name,useFactory: () => {const schema = CategorySchema;schema.plugin(require(‘mongoose-slug-generator’));return schema;},}])
Next we need a data transfer object for carrying data between service and controller.
// We need class-validator to validate api// npm i --save class-validator class-transformerimport { IsNotEmpty } from “class-validator”;export class CategoryDto {@IsNotEmpty()name: string;slug: string;banner: string;}
Next we will create category service —
import { Injectable } from ‘@nestjs/common’;import { InjectModel } from ‘@nestjs/mongoose’;import { Model } from ‘mongoose’;import { Category, CategoryDocument } from ‘./schemas/category.schema’;import { CategoryDto } from ‘./dtos/category-dto’;@Injectable()export class CategoryService {constructor(@InjectModel(Category.name) private catModel: Model<CategoryDocument>) {}async create(categoryDto: CategoryDto): Promise<Category> {const createdCat = new this.catModel(categoryDto);return createdCat.save();}async update(categoryDto: CategoryDto, id: string): Promise<Category> {return this.catModel.findByIdAndUpdate(id, {…categoryDto}, {useFindAndModify: false}).exec();}async findAll(): Promise<Category[]> {return this.catModel.find().exec();}async findOne(id: string): Promise<Category> {return this.catModel.findById(id).exec();}async findOneBySlug(slug: string): Promise<Category> {return this.catModel.findOne({slug}).exec();}async deleteOne(id: string): Promise<Category> {return this.catModel.deleteOne({ _id: id}).exec();}}
And at last the controller
import { Body, Controller, Delete, Get, Param, Post, Put, ValidationPipe } from ‘@nestjs/common’;import { Category } from ‘./schemas/category.schema’;import { CategoryService } from ‘./category.service’;import { CategoryDto } from ‘./dtos/category-dto’;@Controller(‘category’)export class CategoryController {constructor(private readonly catService: CategoryService) {}@Post()// ValidationPipe() will help to validate input body using 'class-validator'
async create(@Body(new ValidationPipe()) categoryDto: CategoryDto) {await this.catService.create(categoryDto);}@Get()async findAll(): Promise<Category[]> {return this.catService.findAll();}@Get(‘:id’)findOne(@Param(‘id’) id: string) {return this.catService.findOne(id);}@Get('categoryBySlug/:slug')findOneBySlug(@Param('slug') slug: string) {return this.catService.findOneBySlug(slug);}@Put(‘:id’)update(@Param(‘id’) id: string, @Body() updateCatDto: CategoryDto) {return this.catService.update(updateCatDto, id);}@Delete(‘:id’)remove(@Param(‘id’) id: string) {return this.catService.deleteOne(id);}}
So we now have /category API with POST, PUT, GET and DELETE with input validation and slugify.
Next we will create the Product module and add relationship between Category and Product.
Github link https://github.com/asif633/nestjs-ecommerce
Thank you.