Using NestJS with MongoDB: A Complete Guide

@rnab
3 min readJan 3, 2025

--

NestJS has gained popularity due to its robust architecture, leveraging TypeScript and the scalability of Node.js. One common need in web applications is working with databases. In this guide, we’ll dive into integrating MongoDB with NestJS using Mongoose, a popular MongoDB object modeling tool for Node.js. By the end of this guide, you’ll have a solid foundation for setting up a NestJS project with MongoDB and performing basic CRUD operations.

Prerequisites

Before we start, ensure you have the following installed:

Setting Up the NestJS Project

First, let’s create a new NestJS project with the Nest CLI:

$ nest new nest-mongo-tutorial
$ cd nest-mongo-tutorial

Installing Dependencies

We’ll need to install Mongoose and the corresponding NestJS package:

$ npm install @nestjs/mongoose mongoose

Configuring MongoDB Connection

Open up the app.module.ts file and import the MongooseModule to set up the connection to MongoDB:

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'),
ItemsModule
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

Replace 'mongodb://localhost/nest' with your MongoDB connection string. If you're using MongoDB Atlas, it will look something like this:

'MONGODB_CONNECTION_STRING'

Creating the Items Module

Next, let’s create an Items module to handle our CRUD operations. We'll use the Nest CLI to generate the module, service, and controller:

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

Defining the Schema

In the items directory, create a new file named item.schema.ts. This file will define the Mongoose schema for our items:

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

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

@Prop()
description: string;

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

@Prop({ default: Date.now })
createdAt: Date;
}

export const ItemSchema = SchemaFactory.createForClass(Item);

Updating the Items Module

Update the items.module.ts file to include the schema and Mongoose module:

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { ItemsService } from './items.service';
import { ItemsController } from './items.controller';
import { Item, ItemSchema } from './item.schema';

@Module({
imports: [MongooseModule.forFeature([{ name: Item.name, schema: ItemSchema }])],
providers: [ItemsService],
controllers: [ItemsController],
})
export class ItemsModule {}

Implementing the Items Service

Now, open items.service.ts and implement the CRUD operations:

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

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

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

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

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

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

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

Creating the Items Controller

Finally, let’s update items.controller.ts to define the API endpoints:

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

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

@Get()
async findAll(): Promise<Item[]> {
return this.itemsService.findAll();
}

@Get(':id')
async findOne(@Param('id') id: string): Promise<Item> {
return this.itemsService.findOne(id);
}

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

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

@Delete(':id')
async delete(@Param('id') id: string): Promise<any> {
return this.itemsService.delete(id);
}
}

Running the Application

Start your NestJS application by running:

$ npm run start

Your NestJS application should now be running and connected to MongoDB. You can test the endpoints using a tool like Postman or cURL.

Conclusion

In this guide, we covered setting up a NestJS project, connecting it to MongoDB using Mongoose, and performing basic CRUD operations. NestJS’s modular structure combined with Mongoose’s robust features provide a powerful foundation for building scalable applications. Happy coding!

Feel free to ask any questions or share your experiences in the comments below!

--

--

@rnab
@rnab

Written by @rnab

Typescript, Devops, Kubernetes, AWS, AI/ML, Algo Trading

No responses yet