O Mongoose com NestJS é uma biblioteca de Modelagem de Dados de Objetos (ODM) para MongoDB e Node.js. Ele oferece validação de esquema, middleware e métodos de construção de consulta integrados. Neste guia, vamos integrar o Mongoose ao NestJS para criar um aplicativo backend estruturado e escalável usando o MongoDB, ideal para quem busca organizar e otimizar o desenvolvimento de aplicações.
Pré-requisitos
- Conhecimento básico de TypeScript e NestJS
- Node.js e NestJS CLI instalados
- Uma instância em execução do MongoDB (local ou baseada na nuvem)
Instalando Dependências
Para usar o Mongoose com NestJS, instale os pacotes necessários:
npm install @nestjs/mongoose mongoose
Para tipos TypeScript:
npm install -D @types/mongoose
Configurando o Mongoose no NestJS
O NestJS fornece o MongooseModule para gerenciar as conexões MongoDB. Adicione-o ao módulo raiz:
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost:27017/nestjs-app', {
useNewUrlParser: true,
useUnifiedTopology: true,
})],
})
export class AppModule {}
Entendendo os Conceitos do Mongoose
1. Schema
Define a estrutura dos documentos em uma coleção. O schema é essencial para garantir a consistência e a integridade dos dados no seu banco de dados MongoDB.
2. Model
Um wrapper para o schema que permite interagir com o banco de dados. O model facilita a execução de operações CRUD (Criar, Ler, Atualizar e Deletar) nos documentos.
3. Document
Uma instância de um model que representa um único registro. Cada documento corresponde a uma entrada específica no banco de dados, seguindo a estrutura definida pelo schema.
4. Middleware
Funções que são executadas antes ou depois de certas ações (por exemplo, salvar um documento). Os middlewares são úteis para adicionar lógica personalizada ao ciclo de vida dos documentos.
5. Virtuals
Propriedades computadas que não são armazenadas no banco de dados. Os virtuals permitem criar campos que são calculados dinamicamente com base em outros campos do documento.
6. Hooks
Funções que são executadas antes ou depois de certas operações do Mongoose (por exemplo, pre-save, post-save). Os hooks são similares aos middlewares, mas são definidos diretamente no schema.
Criando um Schema e Model do Mongoose
Defina um schema usando decorators com @nestjs/mongoose
.
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
@Schema({ timestamps: true })
export class User extends Document {
@Prop({ required: true })
name: string;
@Prop({ unique: true, required: true })
email: string;
@Prop({ default: Date.now })
createdAt: Date;
}
export const UserSchema = SchemaFactory.createForClass(User);
Adicionando Middleware (Hooks)
As funções middleware permitem executar a lógica antes ou depois de certos eventos, como salvar um documento.
UserSchema.pre('save', function(next) {
console.log('User is being saved:', this);
next();
});
Definindo Virtuals
Virtuals permitem criar propriedades computadas que não são armazenadas no MongoDB.
UserSchema.virtual('fullName').get(function() {
return `${this.firstName} ${this.lastName}`;
});
Registrando o Schema no Módulo
Para usar o schema, registre-o em um módulo:
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './user.schema';
import { UserService } from './user.service';
import { UserController } from './user.controller';
@Module({
imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
Criando um Serviço para Operações de Banco de Dados
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from './user.schema';
@Injectable()
export class UserService {
constructor(@InjectModel(User.name) private userModel: Model<User>) {}
async createUser(name: string, email: string): Promise<User> {
const newUser = new this.userModel({ name, email });
return newUser.save();
}
}
Consultando com Mongoose
Encontre todos os usuários:
async getUsers(): Promise<User[]> {
return this.userModel.find().exec();
}
Encontre por ID:
async getUserById(id: string): Promise<User> {
return this.userModel.findById(id).exec();
}
Selecione Campos Específicos:
async getUserByEmail(email: string): Promise<User> {
return this.userModel.findOne({ email }).select('name email').exec();
}
Usando Índices para Otimização de Desempenho
UserSchema.index({ email: 1 });
Encontre com Filtragem:
async getUsersByCreatedDate(date: Date): Promise<User[]> {
return this.userModel.find({ createdAt: { $gte: date } }).exec();
}
Ordenando Resultados:
async getUsersSorted(): Promise<User[]> {
return this.userModel.find().sort({ name: 1 }).exec();
}
Paginação com Limit & Skip:
async getUsersPaginated(page: number, limit: number): Promise<User[]> {
return this.userModel.find().skip((page - 1) * limit).limit(limit).exec();
}
Transações no MongoDB
Para garantir operações atômicas, use transações MongoDB:
const session = await this.userModel.db.startSession();
session.startTransaction();
try {
const user = new this.userModel({ name, email });
await user.save({ session });
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
} finally {
session.endSession();
}
Melhores Práticas para usar Mongoose com NestJS
- Use DTOs para validação e tratamento de requisições.
- Habilite índices para melhor desempenho das consultas.
- Utilize Transações MongoDB para operações atômicas.
- Implemente middleware para logging e tratamento de erros.
- Mantenha as definições de schema limpas e estruturadas.
- Use
.select()
para buscar apenas os campos necessários para eficiência. - Use
.sort()
,.skip()
e.limit()
para melhor gerenciamento de recuperação de dados.
Este guia abrange a configuração do Mongoose com NestJS, definindo schemas, implementando operações CRUD, manipulando transações, indexação, filtragem e melhores práticas. Com esta base, você pode construir aplicações poderosas e otimizadas usando NestJS e MongoDB.
Este conteúdo foi auxiliado por Inteligência Artificial, mas escrito e revisado por um humano.
Via Dev.to