Guia Completo de Mongoose com NestJS e MongoDB

Mongoose com NestJS é uma biblioteca de Modelagem de Dados de Objetos (ODM) para MongoDB e Node.js, que oferece validação de schema, middleware e métodos de construção de consultas integrados. Quer criar um backend estruturado e escalável usando MongoDB? Este guia explica como integrar o Mongoose com NestJS.

Pré-requisitos

Antes de começar, é bom ter:

  • Conhecimento básico de TypeScript e NestJS.
  • Node.js e NestJS CLI instalados.
  • Uma instância do MongoDB em execução (local ou na nuvem).

Instalando Dependências

Para usar o Mongoose com NestJS, instale os pacotes necessários:

npm install @nestjs/mongoose mongoose

E para os tipos TypeScript:

npm install -D @types/mongoose

Configurando o Mongoose no NestJS

O NestJS oferece 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 {}

Conceitos Essenciais do Mongoose

Para dominar o Mongoose com NestJS, é importante entender alguns conceitos chave. Vamos dar uma olhada:

1. Schema

Define a estrutura dos documentos em uma coleção. É como um modelo que seus dados devem seguir.

2. Model

É um invólucro para o schema, permitindo a interação com o banco de dados. Pense nele como uma interface para seus dados.

3. Document

Uma instância de um model que representa um único registro. Cada documento é um conjunto de dados específico.

4. Middleware

Funções que são executadas antes ou depois de certas ações, como salvar um documento. Útil para adicionar lógica extra ao seu fluxo de dados.

5. Virtuals

Propriedades computadas que não são armazenadas no banco de dados. Perfeito para campos que são derivados de outros dados.

6. Hooks

Funções que são executadas antes ou depois de certas operações do Mongoose, como pre-save e post-save. Ótimo para auditoria ou manipulação de dados.

Criando um Schema e Model Mongoose

Para definir um schema, use os decorators com @nestjs/mongoose. Veja como:

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 lógicas antes ou depois de certos eventos, como salvar um documento. Olha só:

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. Veja um exemplo:

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. Assim:

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 no Banco de Dados

Para encapsular a lógica de acesso aos dados, crie um serviço:

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

Agora que você já configurou tudo, veja como realizar algumas consultas básicas:

Encontrar todos os usuários:

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

Encontrar por ID:

async getUserById(id: string): Promise<User> {
  return this.userModel.findById(id).exec();
}

Selecionar 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 });

Encontrar com Filtro:

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 as transações do 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();
}

Se você está começando com MongoDB e quer saber mais sobre o assunto, temos um artigo que pode te ajudar a entender melhor como esse banco de dados funciona.

Boas Práticas

  • Use DTOs para validação e tratamento de requisições.
  • Habilite índices para melhor desempenho das consultas.
  • Use 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, visando eficiência.
  • Use .sort(), .skip() e .limit() para um melhor gerenciamento da recuperação de dados.

Se você também está buscando outras ferramentas, temos um artigo sobre como a revolução do software com IA está mudando tudo.

Com este guia, você tem um bom ponto de partida para construir aplicações poderosas e otimizadas usando NestJS e MongoDB. Explore mais a fundo cada conceito e pratique para se tornar um expert em Mongoose com NestJS!

Este conteúdo foi auxiliado por Inteligência Artificial, mas escrito e revisado por um humano.

Leave a Comment

Exit mobile version