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!