DEV Community

Cover image for NestJS: introdução e aplicação de CRUD usando MongoDB
Kodus for Kodus.community

Posted on • Updated on • Originally published at ezdevs.com.br

NestJS: introdução e aplicação de CRUD usando MongoDB

Fala, devs! Tudo certo?

Se você está neste artigo, é porque deseja entender melhor sobre o NestJS e como é possível criar um CRUD, a base para construção de aplicações back-end, utilizando o banco de dados MongoDB. Então, vamos ao que interessa!

Antes de mais nada, o que é o NestJS?

NestJS é um framework Open Source em Node.js, que trás um modelo de arquitetura que acelera o desenvolvimento de aplicações backend.

Como o próprio site oficial diz:

“A progressive Node.js framework for building efficient, reliable and scalable server-side applications.”

Com uma arquitetura modular, bem parecida com o Angular ou Spring, quem conhece vai se familiarizar com ele, que usa os recursos mais recentes do JavaScript, oferecendo padrões de design e arquitetura consolidada.

Ah, bem importante: NestJS é TypeScript, ok?!

Além de permitir o uso de TypeScript, esta tecnologia oferece uma série de vantagens para aqueles que atuam tanto na programação back-end, como no front-end. Um exemplo disso está na própria organização do seu código, que é bem estruturada e intuitiva, feita através de um model-service-controller, o que facilita a sua utilização.

Mas vamos lá, a ideia aqui, é conhecer este framework, e nada melhor para isso do que vendo ele em ação.

Bom, de início, vamos instalar o NestJS. Para isso, vale ressaltar que é preciso do Node.js e do NPM já instalado.

Instalando o NestJS

nest new nests-start
Enter fullscreen mode Exit fullscreen mode

Instalação do NestJS
NPM ou Yarn? Eu vou de Yarn, porque estou mais habituado.
Seleção do yarn ou npm
Legal, agora temos a estrutura criada e podemos entender o que ela traz. Além disso, precisamos escolher a IDE para seguir com o projeto. Fique a vontade para usar a de sua preferência, eu vou de WebStorm.
Estrutura do NestJS
Agora vamos entender isso aqui:
Nessa estrutura temos o main.ts, que é o ponto de partida da nossa aplicação.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT || 3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

O app.module.ts, que é o core da nossa aplicação, onde são registrados todas as nossas configurações e módulos.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Aqui começa a ficar interessante! Repare no “@Module”. Sim, usamos Decorators. Os Decorators funcionam mais ou menos como os Annotations no Spring.

Bom, agora com o projeto criado, vamos executá-lo.

yarn start:dev
Enter fullscreen mode Exit fullscreen mode

Veja o Hello World em http://localhost:3000, que é a porta que foi setada no main.ts

Mas vamos ao que interessa, não é mesmo? Vamos ao nosso famoso CRUD de users com mongodb.

Implementando o CRUD com MongoDB

Primeiro, vamos limpar esta estrutura, apagando os arquivos:

  • app.controller.spec.ts;
  • app.controler.ts;
  • app.service.ts. Além disso, vamos editar o app.modules.ts, pois ele instanciava o service e o controler que apagamos.
import { Module } from '@nestjs/common';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

E agora a mágica:
Usando o CLI do nest, temos um gerador de CRUD

nest g resource users
Enter fullscreen mode Exit fullscreen mode

Este comando não apenas gera todos os blocos de construção NestJS (módulo, serviço, classes de controlador), mas também uma classe de entidade, classes DTO.

Abaixo, temos o controller gerado para REST API:

import { 
  Controller, 
  Get, 
  Post, 
  Body, 
  Patch, 
  Param, 
  Delete 
} from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(id);
  }
}
Enter fullscreen mode Exit fullscreen mode

Vamos editar o nosso app.modules, registrando nosso users.

import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [UsersModule],
  controllers: [UsersController],
  providers: [UsersService],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Vamos começar pelo nosso create-users.dto.ts, usando o código abaixo.

export class CreateUserDto {
  email: string;
  name: string;
  password: string;
}
Enter fullscreen mode Exit fullscreen mode

Com a criação do extend CreateUserDto, o update-users.dto.ts, então, já está pronto.

Vamos agora para nossa classe de entidade. Para isso, vamos precisar instanciar o mongo, eu vou usar o mongo Atlas, que para um projeto starter, funciona muito bem.

Na documentação do NestJS, mais especificamente na seção TECHNIQUES, temos as instruções para trabalhar com o mongo.

Vamos instalar o mongoose e a tipagem.

yarn add @nestjs/mongoose mongoose
Enter fullscreen mode Exit fullscreen mode

Vamos editar o arquivo /users/entities/user.entity.ts

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

export type UserDocument = User & Document;

@Schema()
export class User {
  @Prop()
  name: string;

  @Prop()
  email: string;

  @Prop()
  password: string;
}

export const UserSchema = SchemaFactory.createForClass(User);
Enter fullscreen mode Exit fullscreen mode

Quase tudo pronto, falta agora configurar o acesso ao mongo e os methods no service e os endpoints no controller.

Vamos lá, no users.module.ts, importar a conexão com o mongo.

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User, UserSchema } from './entities/user.entity';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
  ],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}
Enter fullscreen mode Exit fullscreen mode

No users.services.ts, editamos os methods create(), findAll(), findOn(), update() e remove() que foram criados pelo CLI.

import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User, UserDocument } from './entities/user.entity';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';

@Injectable()
export class UsersService {
  constructor(@InjectModel(User.name) private userModel: Model<UserDocument>) {
  }
  create(createUserDto: CreateUserDto) {
    const user = new this.userModel(createUserDto);
    return user.save();
    }

  findAll() {
    return this.userModel.find();
  }

  findOne(id: string) {
    return this.userModel.findById(id);
  }

  update(id: string, updateUserDto: UpdateUserDto) {
    return this.userModel
      .findByIdAndUpdate(
        {
          _id: id,
        },
        {
          $set: updateUserDto,
        },
        {
          new: true,
        },
      )
      .exec();
  }

  remove(id: string) {
    return this.userModel.deleteOne({ _id: id }).exec();
  }
}
Enter fullscreen mode Exit fullscreen mode

O Controller já está pronto, só precisamos editar, pois o type do nosso id é string e não number.

import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(id);
  }
}
Enter fullscreen mode Exit fullscreen mode

Criamos também um arquivo .env na raiz do projeto, setando uma variável com a string de conexão com o seu mongodb.

MONGODB = 'mongodb+srv://nestjs:nestjs@clusteralexmaxdev.ex4ok.mongodb.net/test'
Enter fullscreen mode Exit fullscreen mode

E tudo pronto, estamos ON FIRE.
Resposta em json
A ideia foi apresentar o framework NestJS e mostrar na prática o quão produtivo é desenvolver com este framework.

Se você acompanhou este conteúdo até o final, tenho certeza de que conseguiu desenvolver a sua primeira aplicação de CRUD através do NestJS com MongoDB.

Vale ressaltar que estes conceitos são mais introdutórios e voltarei em outros artigos trazendo um pouco mais sobre este ecossistema do NestJS. (Falando em ecossistema, conheça mais sobre o ecossistema da Kodus

E, caso queira se aprofundar neste exemplo sobre NestJS, recomendo que você dê uma olhada nesse repositório no GitHub.

Grande abraço e até a próxima.


Esse conteúdo é um repost da Kodus para o membro da nossa comunidade Alexander Yokogawa. Faça parte da comunidade e poste aqui também!

Top comments (0)