Overview
NestJS, a powerful Node.js framework, can be effectively integrated with MongoDB, a popular NoSQL database. This tutorial guides you through the process step by step.
By the end of this tutorial, you will know how to set up a NestJS project configured to connect with a MongoDB database, use Mongoose for schema models, and perform CRUD operations. We’ll take a practical approach, walking through essential steps and providing code snippets to illustrate the integration.
Prerequisites:
- Node.js installed
- NPM or Yarn as a package manager
- Basic knowledge of TypeScript and NestJS
- MongoDB account and database set up
Setting up a NestJS Project
npm i -g @nestjs/cli
nestjs new project-name
This command installs the NestJS CLI globally and scaffolds a new project.
Installing Mongoose and NestJS/Mongoose
npm install @nestjs/mongoose mongoose
These packages provide the necessary tools to integrate MongoDB via Mongoose in your application.
Configuring the MongoDB Connection
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
@Module({
imports: [
MongooseModule.forRoot('mongodb+srv://your-db-uri', {
useNewUrlParser: true,
useUnifiedTopology: true,
}),
],
})
export class AppModule {}
Replace ‘your-db-uri’ with your actual MongoDB URI. The options `useNewUrlParser` and `useUnifiedTopology` are included for compatibility.
Defining a Schema Model
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
@Schema()
export class Cat extends Document {
@Prop({ required: true })
name: string;
@Prop()
age: number;
@Prop()
breed: string;
}
export const CatSchema = SchemaFactory.createForClass(Cat);
This code defines a simple `Cat` schema with the `@Prop` decorator to denote the properties.
Creating a Module
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Cat, CatSchema } from './schemas/cat.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }]),
],
})
export class CatsModule {}
The `CatsModule` incorporates the `Cat` schema, making it available within this specific module.
Service Layer
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Cat } from './schemas/cat.schema';
@Injectable()
export class CatsService {
constructor(@InjectModel(Cat.name) private catModel: Model) {}
async create(createCatDto: { name: string; age: number; breed: string }): Promise {
const createdCat = new this.catModel(createCatDto);
return createdCat.save();
}
async findAll(): Promise<Cat[]> {
return this.catModel.find().exec();
}
}
The `CatsService` utilizes the model to provide create and find operations for the cat entities.
Controller Layer
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './schemas/cat.schema';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
async create(@Body() createCatDto: { name: string; age: number; breed: string }): Promise {
return this.catsService.create(createCatDto);
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
The `CatsController` exposes endpoints to create a new cat and fetch all cats, relying on the service layer for business logic.
CRUD in Action
To see this in action, use your API testing tool to hit the endpoints such as `POST /cats` to create and `GET /cats` to retrieve cat entries.
Advanced: Data Transfer Objects (DTOs)
Now let’s cover some advanced topics including using DTOs for data transfer, implementing middleware for validation, using async hooks with Mongoose, and incorporating transactions.
import { IsString, IsNumber } from 'class-validator';
export class CreateCatDto {
@IsString()
readonly name: string;
@IsNumber()
readonly age: number;
@IsString()
readonly breed: string;
}
DTOs like `CreateCatDto` help ensure that data conforms to the specified format and types.
Conclusion
Integration of MongoDB with NestJS empowers developers to build scalable and maintainable applications. Using Mongoose within NestJS combines the robustness of TypeScript with the flexibility of MongoDB. Take the concepts here as a springboard to create complex, production-grade apps.