1 / 12
Modulo 6 / Back-End com Node.js

Express + MongoDB

Integrando o banco de dados à API com Mongoose.

school Aula 29 schedule 2 horas

ODM

O que é Mongoose?

data_object Object Document Mapper

  • Biblioteca para modelar dados no MongoDB
  • Define schemas (estrutura) para os documentos
  • Validação automática de dados
  • API simplificada para operações CRUD
  • Middleware (hooks) para lógica pre/post operações

download Instalação

$ npm install mongoose dotenv // .env MONGODB_URI=mongodb+srv://user:pass@ cluster0.abc.mongodb.net/minha-api // Estrutura do projeto minha-api/ ├── models/ │ └── Aluno.js ├── controllers/ │ └── alunoController.js ├── routes/ │ └── alunoRoutes.js ├── .env ├── .gitignore └── index.js

Conectando

Conexão com o banco

code index.js

require('dotenv').config(); const express = require('express'); const mongoose = require('mongoose'); const app = express(); app.use(express.json()); // Conectar ao MongoDB mongoose.connect(process.env.MONGODB_URI) .then(() => console.log('✅ MongoDB conectado!')) .catch(err => console.log('❌ Erro:', err)); // Rotas app.use('/alunos', require('./routes/alunoRoutes')); app.listen(3000, () => console.log('Servidor em http://localhost:3000'));

Modelagem

Schema e Model

code models/Aluno.js

const mongoose = require('mongoose'); const alunoSchema = new mongoose.Schema({ nome: { type: String, required: [true, 'Nome é obrigatório'], trim: true }, email: { type: String, required: true, unique: true, lowercase: true }, idade: { type: Number, min: 16, max: 100 }, curso: { type: String, default: 'Programação Web' }, notas: [Number], ativo: { type: Boolean, default: true } }, { timestamps: true }); module.exports = mongoose.model('Aluno', alunoSchema);
timestamps: true adiciona automaticamente createdAt e updatedAt em cada documento.

Lógica

Controller CRUD

code controllers/alunoController.js

const Aluno = require('../models/Aluno'); // Listar todos exports.listar = async (req, res) => { const alunos = await Aluno.find(); res.json(alunos); }; // Buscar por ID exports.buscar = async (req, res) => { const aluno = await Aluno.findById(req.params.id); if (!aluno) return res.status(404).json({ erro: 'Nao encontrado' }); res.json(aluno); }; // Criar exports.criar = async (req, res) => { const aluno = await Aluno.create(req.body); res.status(201).json(aluno); }; // Atualizar exports.atualizar = async (req, res) => { const aluno = await Aluno.findByIdAndUpdate( req.params.id, req.body, { new: true } ); res.json(aluno); }; // Remover exports.remover = async (req, res) => { await Aluno.findByIdAndDelete(req.params.id); res.json({ mensagem: 'Removido com sucesso' }); };

Routing

Arquivo de rotas

route routes/alunoRoutes.js

const router = require('express').Router(); const ctrl = require( '../controllers/alunoController' ); router.get('/', ctrl.listar); router.get('/:id', ctrl.buscar); router.post('/', ctrl.criar); router.put('/:id', ctrl.atualizar); router.delete('/:id', ctrl.remover); module.exports = router;

api Endpoints gerados

GET /alunos Listar todos
GET /alunos/:id Buscar um
POST /alunos Criar
PUT /alunos/:id Atualizar
DELETE /alunos/:id Remover

Segurança

Validação de dados

verified Validadores do Mongoose

nome: { type: String, required: [true, 'Nome obrigatório'], minlength: [3, 'Mínimo 3 caracteres'], maxlength: 100, trim: true }, email: { type: String, required: true, unique: true, match: [/^\S+@\S+\.\S+$/, 'Email inválido'] }, idade: { type: Number, min: [16, 'Mín. 16 anos'], max: [100, 'Máx. 100 anos'] }

error Tratando erros

exports.criar = async (req, res) => { try { const aluno = await Aluno.create( req.body ); res.status(201).json(aluno); } catch (err) { if (err.name === 'ValidationError') { res.status(400).json({ erro: err.message }); } else { res.status(500).json({ erro: 'Erro do servidor' }); } } };

Consultas

Queries avançadas

search Filtros e seleção

// Buscar com filtro const ativos = await Aluno.find({ ativo: true }); // Selecionar campos específicos const nomes = await Aluno .find() .select('nome email'); // Ordenar e limitar const top5 = await Aluno .find() .sort({ nome: 1 }) .limit(5);

filter_alt Busca com query params

// GET /alunos?curso=Web&ativo=true exports.listar = async (req, res) => { const filtro = {}; if (req.query.curso) filtro.curso = req.query.curso; if (req.query.ativo) filtro.ativo = req.query.ativo; const alunos = await Aluno .find(filtro) .sort({ nome: 1 }); res.json(alunos); };

Segurança

dotenv e .gitignore

key Arquivo .env

# .env (NÃO versionar!) MONGODB_URI=mongodb+srv://user:pass@... PORT=3000 JWT_SECRET=minha-chave-secreta # .gitignore node_modules/ .env .DS_Store

code Usando no código

// No topo do index.js require('dotenv').config(); // Acessar variáveis const PORT = process.env.PORT || 3000; const URI = process.env.MONGODB_URI;
warning Se o .env for commitado no Git, suas senhas estarão expostas publicamente!

Visão geral

Fluxo completo

Cliente
Thunder/Postman
Rota
Express Router
Controller
Lógica
Model
Mongoose
MongoDB
Atlas
index.js
Servidor + conexão
routes/
Endpoints HTTP
controllers/
Lógica de negócio
models/
Schema + validação

Hora de praticar

Exercício prático

api API de Alunos com MongoDB

  1. Crie o projeto com Express + Mongoose + dotenv
  2. Conecte ao seu cluster MongoDB Atlas
  3. Crie o model Aluno com validações
  4. Implemente o controller com CRUD completo e try/catch
  5. Crie as rotas e teste com Thunder Client
  6. Adicione filtros por query params (ex: ?curso=Web)
lightbulb Desafio extra: adicione um model de Curso e relacione com os alunos.
Próxima aula

Aula 30

Autenticação com JWT e sessões.

task_alt O que aprendemos hoje

  • check_circle O que é Mongoose (ODM) e instalação
  • check_circle Conexão com MongoDB Atlas via dotenv
  • check_circle Schema, Model e validações
  • check_circle Controller CRUD com async/await e try/catch
  • check_circle Queries avançadas e segurança com .env
Próxima aula
auto_stories Referência: Mongoose Docs
Leandro Medeiros