2-how-to-create-a-scalable-application-using-nestjs-and-mongodb.html

How to Create a Scalable Application Using NestJS and MongoDB

Building scalable applications is a primary goal for developers today, as it allows for efficient resource management and enhanced user experience. NestJS, a progressive Node.js framework, combined with MongoDB, a NoSQL database, is a perfect duo to achieve this goal. This article will guide you through the steps to create a scalable application using NestJS and MongoDB, complete with code examples and best practices.

Understanding NestJS and MongoDB

What is NestJS?

NestJS is a framework for building efficient, scalable Node.js server-side applications. It leverages TypeScript and incorporates object-oriented programming, functional programming, and reactive programming principles. Key features include:

  • Modular Architecture: Encourages the separation of concerns, making code easier to manage and test.
  • Dependency Injection: Facilitates the management of application components.
  • Support for WebSockets and Microservices: Enhances real-time capabilities and supports distributed systems.

What is MongoDB?

MongoDB is a NoSQL database that stores data in flexible, JSON-like documents. This allows for dynamic schemas, making it easy to adapt to changing application requirements. Key advantages include:

  • Scalability: Horizontal scaling through sharding.
  • Performance: High read and write throughput.
  • Flexibility: Schema-less data storage adapts to evolving application needs.

Setting Up Your Environment

Prerequisites

Before diving into the code, ensure you have the following installed:

  • Node.js (v12 or higher)
  • MongoDB (local installation or MongoDB Atlas)
  • NestJS CLI

To install the NestJS CLI, run:

npm install -g @nestjs/cli

Creating a New NestJS Project

Create a new NestJS project by running:

nest new scalable-app
cd scalable-app

Installing Dependencies

Add the MongoDB driver and Mongoose (an ODM for MongoDB):

npm install @nestjs/mongoose mongoose

Building a Scalable Application

Step 1: Setting Up MongoDB Connection

Open the app.module.ts file to set up the MongoDB connection. You can configure your MongoDB connection string here.

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ItemsModule } from './items/items.module';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/nest'), // Replace with your MongoDB URI
    ItemsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Step 2: Creating a Module for Your Feature

Generate an Items module:

nest generate module items
nest generate service items
nest generate controller items

Step 3: Defining a Schema

Create a schema for your items. In items/schemas/item.schema.ts, define the structure of your data:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

@Schema()
export class Item extends Document {
  @Prop({ required: true })
  name: string;

  @Prop({ required: true })
  description: string;

  @Prop({ required: true })
  price: number;
}

export const ItemSchema = SchemaFactory.createForClass(Item);

Step 4: Implementing the Service

In items/items.service.ts, implement the CRUD operations:

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Item } from './schemas/item.schema';

@Injectable()
export class ItemsService {
  constructor(@InjectModel(Item.name) private itemModel: Model<Item>) {}

  async create(item: Item): Promise<Item> {
    const newItem = new this.itemModel(item);
    return newItem.save();
  }

  async findAll(): Promise<Item[]> {
    return this.itemModel.find().exec();
  }

  async findOne(id: string): Promise<Item> {
    return this.itemModel.findById(id).exec();
  }

  async update(id: string, item: Item): Promise<Item> {
    return this.itemModel.findByIdAndUpdate(id, item, { new: true }).exec();
  }

  async delete(id: string): Promise<Item> {
    return this.itemModel.findByIdAndRemove(id).exec();
  }
}

Step 5: Creating the Controller

In items/items.controller.ts, create endpoints for the operations:

import { Controller, Get, Post, Body, Param, Put, Delete } from '@nestjs/common';
import { ItemsService } from './items.service';
import { Item } from './schemas/item.schema';

@Controller('items')
export class ItemsController {
  constructor(private readonly itemsService: ItemsService) {}

  @Post()
  create(@Body() item: Item) {
    return this.itemsService.create(item);
  }

  @Get()
  findAll() {
    return this.itemsService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.itemsService.findOne(id);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() item: Item) {
    return this.itemsService.update(id, item);
  }

  @Delete(':id')
  delete(@Param('id') id: string) {
    return this.itemsService.delete(id);
  }
}

Step 6: Testing Your Application

Run your application using:

npm run start

You can test your API using tools like Postman or CURL. Try hitting the endpoints:

  • POST /items to create a new item
  • GET /items to retrieve all items
  • GET /items/:id to retrieve a specific item
  • PUT /items/:id to update an item
  • DELETE /items/:id to delete an item

Best Practices for Scalability

  • Use Caching: Implement caching strategies to reduce database load.
  • Horizontal Scaling: Use sharding in MongoDB for distributing data across multiple servers.
  • Microservices: Break your application into smaller services for better management and scalability.
  • Monitoring: Use tools like Prometheus or Grafana to monitor application performance.

Conclusion

Creating a scalable application with NestJS and MongoDB is straightforward yet powerful. By following the steps outlined in this article, you can build a robust application that meets the demands of modern users. Embrace the principles of modular architecture and make use of MongoDB's flexibility to ensure your application can grow seamlessly. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.