4-building-scalable-microservices-with-nestjs-and-mongodb.html

Building Scalable Microservices with NestJS and MongoDB

In today's fast-paced development environment, building scalable applications is a necessity. Microservices architecture has become a popular choice due to its modularity, flexibility, and ease of deployment. In this article, we will delve into how to build scalable microservices using NestJS and MongoDB. NestJS is a progressive Node.js framework, while MongoDB is a NoSQL database that allows for flexible data modeling. Together, they make an excellent stack for developing modern applications.

What are Microservices?

Definition

Microservices are an architectural style that structures an application as a collection of loosely coupled services. Each service is independently deployable, scalable, and can be developed using different programming languages or technologies.

Use Cases

Microservices are particularly beneficial for:

  • Large-scale applications: They allow different teams to work on different services simultaneously, speeding up development.
  • Frequent updates: Services can be updated independently without affecting the entire system.
  • Diverse technology stacks: Different services can use different technologies best suited for their tasks.

Why Choose NestJS and MongoDB?

NestJS

NestJS is built on top of Node.js and is heavily inspired by Angular, which makes it a great choice for developers familiar with TypeScript and modular programming. It provides an out-of-the-box application architecture that’s easy to extend.

MongoDB

MongoDB's document-oriented data model provides flexibility in how data is stored, making it easier to change and adapt to new requirements. Its horizontal scaling capabilities allow applications to handle increased loads efficiently.

Setting Up Your Environment

To get started, ensure you have the following installed:

  • Node.js (version 14 or later)
  • MongoDB (locally or through a cloud service like MongoDB Atlas)
  • Nest CLI (install using npm install -g @nestjs/cli)

Creating a New NestJS Project

  1. Initialize a new NestJS project: bash nest new microservices-app cd microservices-app

  2. Install necessary packages: bash npm install @nestjs/mongoose mongoose

  3. Set up MongoDB: If you're using MongoDB Atlas, create a new cluster and obtain your connection string. If using locally, ensure the MongoDB service is running.

Creating a Simple Microservice

Step 1: Setting Up MongoDB Connection

Create a new file named app.module.ts in the src folder:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersModule } from './users/users.module';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/nest'), // replace with your MongoDB connection string
    UsersModule,
  ],
})
export class AppModule {}

Step 2: Creating a User Module

  1. Generate a new module: bash nest g module users nest g service users nest g controller users

  2. Define User Schema:

Create a new file user.schema.ts in the users folder:

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

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

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

  @Prop()
  age: number;
}

export const UserSchema = SchemaFactory.createForClass(User);

Step 3: Implementing User Service

Update the users.service.ts:

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from './user.schema';

@Injectable()
export class UsersService {
  constructor(@InjectModel(User.name) private userModel: Model<User>) {}

  async create(userDto: CreateUserDto): Promise<User> {
    const newUser = new this.userModel(userDto);
    return newUser.save();
  }

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

Step 4: Implementing User Controller

Update the users.controller.ts:

import { Body, Controller, Get, Post } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './create-user.dto'; // Create this DTO

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  async findAll() {
    return this.usersService.findAll();
  }
}

Step 5: Creating CreateUser DTO

Create a new file create-user.dto.ts in the users folder:

export class CreateUserDto {
  name: string;
  email: string;
  age?: number;
}

Running the Application

After setting everything up, you can run your NestJS application:

npm run start:dev

Visit http://localhost:3000/users to see the users endpoint. You can use tools like Postman to test the POST and GET requests.

Troubleshooting Common Issues

  • MongoDB Connection Errors: Ensure that your MongoDB service is running and that you have the correct connection string.
  • TypeScript Errors: Ensure that your DTOs and schemas are correctly defined and imported.
  • CORS Issues: If you're calling your API from a different origin, you might need to enable CORS in your NestJS application.

Conclusion

Building scalable microservices with NestJS and MongoDB is an excellent way to create modular, maintainable applications. This guide has provided you with a foundational setup, from configuring your environment to creating your first microservice. As you continue to develop your application, consider exploring advanced topics like authentication, service discovery, and API gateways to further enhance your microservices architecture.

By leveraging the powerful capabilities of NestJS and MongoDB, you can set the stage for a robust and scalable application that can meet the demands of today’s users. 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.