Como criar um CRUD com JavaScript usando Node.js, Express e MongoDB

Neste post vamos aprender do zero a criar um CRUD com Javascript, usando Node.js, Express e MongoDB.

CRUD significa Create (Criar), Read (Ler), Update (Atualizar) e Delete (Deletar), operações essenciais para qualquer aplicação que lida com dados. Vamos construir uma API simples para gerenciar vendas mensais, onde poderemos criar, ler, atualizar e deletar registros de vendas.

Se você quer entender do começo ao fim como tudo funciona, está no lugar certo. Aqui você vai aprender a fazer a aplicação, conectar com o banco de dados, criar rotas e muito mais.]

Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:

O que é CRUD e para que serve?

CRUD são as iniciais de Create (Criar), Read (Ler), Update (Atualizar) e Delete (Deletar), as operações básicas que você pode realizar em um banco de dados.

 Quando você tem uma API que faz essas operações, você consegue:

  • Criar novos elementos.
  • Ler todos os elementos existentes.
  • Atualizar elementos existentes.
  • Deletar elementos.

Essas quatro ações são fundamentais para criar APIs RESTful (quer saber mais? Aprenda a criar uma API REST com Node.js do zero!), que seguem padrões de comunicação entre sistemas.

No nosso caso, vamos usar o MongoDB como banco de dados e o Node.js com Express para criar a API.

Como configurar o MongoDB

Antes de começar, você precisa configurar o MongoDB.

Siga os passos abaixo:

  1. Crie uma conta no MongoDB Atlas: Se você ainda não tem uma conta, cadastre-se no MongoDB Atlas.
  2. Crie um Cluster: Após logar, crie um novo projeto e um cluster. Na primeira vez, você pode criar um cluster gratuito.
  3. Autorize seu IP: No painel do MongoDB Atlas, vá em Network Access e adicione seu IP para permitir a conexão.
  4. Obtenha a URI de conexão: No painel do cluster, clique em Connect e selecione Drivers. Copie a URI de conexão, que será usada no nosso código (veremos isso depois).
conectando com o cluster no site do mongodb
Conecte-se ao cluster
criando um banco do de dados no site do mongodb
Crie um banco de dados

Como criar seu projeto Node.js

Vamos começar criando um novo projeto Node.js. No VS Code, crie uma pasta chamada aula e execute os seguintes comandos no terminal do programa:

Codigo
cd aula
Codigo
npm init -y

Isso inicializará um projeto Node.js com um arquivo package.json na pasta aula.

Agora, vamos instalar as dependências necessárias:

Codigo
npm install express mongoose dotenv

O que elas fazem?

  • Express é um framework web para Node.js. Facilita a criação de APIs.
  • Mongoose é uma biblioteca que modela objetos MongoDB.
  • dotenv gerencia variáveis de ambiente.

Configurando o servidor Express

Crie um arquivo chamado server.js e adicione o seguinte código:

JavaScript
import express from "express";
import dotenv from "dotenv";
import mongoose from "mongoose";
import VendaMensal from "./VendaMensal.js";
dotenv.config();
const app = express();
const PORT = 3000;
app.use(express.json());
const connectDB = async () => {
  try {
    await mongoose.connect(process.env.MONGO_URI);
    console.log("Conectado ao MongoDB");
  } catch (error) {
    console.log("Erro ao conectar com o MongoDB", error);
  }
};
connectDB();
app.listen(PORT, () => console.log(`O servidor está rodando na porta ${PORT}`));

Explicação:

  • dotenv.config() carrega as variáveis de ambiente do arquivo .env.
  • mongoose.connect() faz se conectar ao banco de dados MongoDB usando a URI fornecida no arquivo .env.
  • app.use(express.json()): Middleware para parsear o corpo das requisições como JSON.

Criando as variáveis de ambiente

Clique com o botão direito na pasta e crie um arquivo chamado .env.

Dentro dele, crie uma variável chamada MONGO_URI com a senha da cluster fornecida no site do MongoDB.

acessando a URI do banco de dados no site do mongodb
Copie a URI do site do MongoDB
colando a URI na variável do arquivo .env
Cole em uma variável no arquivo .env

Criando o Modelo de Dados

Agora, vamos criar um modelo para as vendas mensais. Crie um arquivo chamado VendaMensal.js e adicione o seguinte código:

JavaScript
import mongoose from "mongoose";
const VendaMensalSchema = new mongoose.Schema({
  mes: Number,
  valorVendido: Number,
});
export default mongoose.model("VendaMensal", VendaMensalSchema);

Explicação:

  • mongoose.Schema define a estrutura do documento no MongoDB.
  • mongoose.model cria um modelo a partir do schema, que será usado para interagir com a coleção no banco de dados.
  • export default mongoose.model exporta o modelo e faz com que ele possa ser importado e usado pelo server.js.

Implementando as Rotas CRUD

Agora vamos implementar as operações CRUD na nossa API.

CREATE (Criar)

Para criar uma nova venda mensal, adicione a seguinte rota no arquivo server.js:

JavaScript
app.post("/vendas", async (req, res) => {
  try {
    const novaVenda = await VendaMensal.create(req.body);
    res.json(novaVenda);
  } catch (error) {
    res.json({ error: error.message });
  }
});

READ (Ler)

Para listar todas as vendas mensais, adicione a seguinte rota:

JavaScript
app.get("/vendas", async (req, res) => {
  try {
    const vendasMensais = await VendaMensal.find();
    res.json(vendasMensais);
  } catch (error) {
    res.json({ error: error.message });
  }
});

UPDATE (Atualizar)

Para atualizar uma venda mensal existente, adicione a seguinte rota:

JavaScript
app.put("/vendas/:id", async (req, res) => {
  try {
    const vendaMensalAtualizada = await VendaMensal.findByIdAndUpdate(
      req.params.id,
      req.body,
      { new: true }
    );
    res.json(vendaMensalAtualizada);
  } catch (error) {
    res.json({ error: error.message });
  }
});

DELETE (Deletar)

Para deletar uma venda mensal, adicione a seguinte rota:

JavaScript
app.delete("/vendas/:id", async (req, res) => {
  try {
    const vendaMensalDeletada = await VendaMensal.findByIdAndDelete(
      req.params.id
    );
    res.json(vendaMensalDeletada);
  } catch (error) {
    res.json({ error: error.message });
  }
});

Testando a API

Agora que todas as rotas estão implementadas, você pode testar a API usando ferramentas como Postman ou Insomnia. Certifique-se de que o servidor está rodando:

node api.js

Exemplos de Requisições:

  • POST /vendas: Cria uma nova venda mensal.
  • GET /vendas: Lista todas as vendas mensais.
  • PUT /vendas/:id: Atualiza uma venda mensal existente.
  • DELETE /vendas/:id: Deleta uma venda mensal.
Testando a API no REQBIN

Conclusão - Como fazer CRUD com JavaScript usando Node.js, Express e MongoDB

Neste tutorial, criamos uma API completa e aprendemos a usar os comandos CRUD com Node.js, Express e MongoDB.

Aprendemos como configurar o servidor, criar modelos de dados e implementar as operações básicas de CRUD. Este é um ótimo ponto de partida para construir aplicações mais complexas que envolvem manipulação de dados. Agora vamos descobrir como acontece a comunicação entre front e back-end

Ícone JavaScriptJavaScript Impressionador

Como usar JavaScript em qualquer empresa e qualquer área, com exemplos totalmente aplicados à realidade do Mercado de Trabalho, seja para se tornar um Desenvolvedor Front End, Backend, Full Stack ou Mobile.

Começar agoraSeta para a direita
Fundo JavaScriptTelas JavaScript

Como o Front-end se Comunica com o Back-end?

A comunicação entre front-end e back-end é base da maioria das aplicações web.

O front-end (interface do usuário) interage com o back-end (servidor e lógica) por meio de requisições HTTP como vimos, geralmente via APIs.

Neste guia, mostramos como configurar um projeto full stack simples, com React no front-end e Node.js com Express no back-end, para criar uma aplicação que envia e recebe dados dinamicamente.

Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:

Como organizar um projeto full stack?

Separar front-end e back-end em pastas distintas é uma prática essencial para manter o código organizado e escalável.

  • Estrutura do projeto:
    • /frontend: Contém o código React (criado com Vite, como mostrado na aula anterior).
    • /backend: Contém o servidor Node.js com Express.
  • Benefício: Facilita manutenção, testes e trabalho em equipe, além de permitir deploys independentes.

Como o front-end em React faz requisições ao back-end?

No front-end, usamos React para criar uma interface simples com um input, um botão e uma área para exibir mensagens. A lógica principal está em uma função assíncrona que usa fetch para enviar dados ao back-end.

  • Estrutura do componente:
    • Um input captura o nome do usuário.
    • Um botão dispara a requisição ao clicar.
    • Uma mensagem condicional exibe a resposta do back-end ou um erro.
  • Exemplo de código (App.jsx): import { useState } from 'react'; import './App.css'; function App() { const [nome, setNome] = useState(''); const [mensagem, setMensagem] = useState(''); const enviarNome = async () => { if (!nome) return; // Evita enviar nome vazio const resposta = await fetch('http://localhost:3001/api/saudacao', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ nome }) }); const dados = await resposta.json(); if (resposta.ok) { setMensagem(dados.mensagem); } else { setMensagem(`Erro: ${dados.erro}`); } }; return ( <div className="container"> <h1>Enviar Saudação</h1> <input type="text" value={nome} onChange={(e) => setNome(e.target.value)} placeholder="Digite seu nome" /> <button onClick={enviarNome} disabled={!nome}>Enviar</button> {mensagem && <p>{mensagem}</p>} </div> ); } export default App;
  • Como funciona:
    • O estado nome armazena o valor do input.
    • A função enviarNome usa fetch para enviar um POST com o nome ao endpoint /api/saudacao.
    • A resposta do back-end é convertida em JSON e atualiza o estado mensagem.

Como configurar o back-end com Node.js e Express?

O back-end usa Node.js com Express para criar um servidor que responde às requisições do front-end. Como a configuração do Node.js e Express foi mostrada na aula anterior, focaremos na lógica do servidor.

  • Código do servidor (server.js): const express = require('express'); const cors = require('cors'); const app = express(); app.use(cors()); // Permite requisições de diferentes domínios app.use(express.json()); // Converte corpo da requisição em JSON app.post('/api/saudacao', (req, res) => { const { nome } = req.body; if (!nome) { return res.status(400).json({ erro: 'Nome obrigatório' }); } res.json({ mensagem: `Olá, ${nome}, seja bem-vindo!` }); }); app.listen(3001, () => console.log('Servidor rodando na porta 3001'));
  • Como funciona:
    • O middleware cors permite que o front-end (porta 5173) acesse o back-end (porta 3001).
    • O middleware express.json() processa o corpo da requisição como JSON.
    • O endpoint /api/saudacao verifica se o campo nome foi enviado e retorna uma saudação ou erro.

Como otimizar a interação front-end e back-end?

Para tornar a aplicação mais robusta, implementamos validações nos dois lados:

  • No front-end:
    • O botão é desabilitado se o input estiver vazio (disabled={!nome}), evitando requisições desnecessárias.
    • A função enviarNome verifica se nome existe antes de enviar a requisição.
  • No back-end:
    • Valida se nome está presente no corpo da requisição, retornando um erro 400 se ausente.
    • Usa status HTTP (200 para sucesso, 400 para erro) para clareza.

Tabela: Validações no Front-end e Back-end

CamadaValidaçãoBenefício
Front-endBotão desabilitado sem nomeEvita requisições inválidas
Front-endVerificação de nome antes do fetchReduz chamadas desnecessárias ao servidor
Back-endVerificação de nome no endpointGarante respostas consistentes
Back-endStatus HTTP 400 para errosComunica falhas claramente

Como exibir respostas dinâmicas no front-end?

A resposta do back-end é exibida dinamicamente no front-end usando o estado mensagem:

  • Se a requisição for bem-sucedida (resposta.ok), exibe a saudação (ex.: “Olá, Diego, seja bem-vindo!”).
  • Se houver erro (ex.: nome vazio), exibe a mensagem de erro (ex.: “Erro: Nome obrigatório”).

Essa lógica condicional usa o operador && no JSX para renderizar o parágrafo apenas se mensagem existir:

HTML
{mensagem && <p>{mensagem}</p>}

Por que usar fetch em vez de Axios?

Neste exemplo, usamos fetch, que é nativo do JavaScript, por sua simplicidade. O Axios, uma biblioteca alternativa, oferece vantagens como tratamento automático de JSON e configuração mais fácil de interceptores, mas exige instalação adicional. Para projetos simples, fetch é suficiente, mas para aplicações complexas, o Axios pode ser mais prático.

Conclusão - a comunicação entre front e back-end

A comunicação entre front-end e back-end é essencial para aplicações web full stack. Usando React e Node.js com Express, você pode criar sistemas interativos que enviam dados, processam requisições e exibem respostas dinâmicas. Organizar o projeto em pastas separadas, validar dados nos dois lados e usar fetch para requisições HTTP são práticas fundamentais. Experimente este exemplo e explore como integrar APIs em seus projetos para criar aplicações robustas.

Se você quer acessar mais conteúdos como esse com aulas e tutoriais sobre JavaScript, confira os outros posts do nosso blog!

Este conteúdo também está disponível em formato de vídeo! Se preferir, veja aqui embaixo ou entre no nosso canal do YouTube!

O que você aprende neste vídeo

Resposta rápida: A aula constrói do zero uma API de vendas mensais em Node.js com Express, ligada ao MongoDB pelo Mongoose, e implementa as quatro operações do CRUD, testando cada uma. Continua uma aula anterior com a primeira API, e a próxima usa esses dados em gráficos.

Neste vídeo (31 min):

  • 2:29 - Cluster gratuito no MongoDB e string de conexão para o Mongoose
  • 5:12 - Iniciar o projeto e instalar express, mongoose e dotenv
  • 7:57 - Arquivo .env com a conexão do Mongo
  • 10:33 - Função de conexão com o banco usando mongoose.connect
  • 11:36 - Liberar o acesso por IP no Network Access
  • 13:05 - Erro de importação e o ajuste no package.json
  • 15:33 - Modelo da venda mensal com o schema do Mongoose
  • 19:06 - Preparar o Express para receber JSON
  • 21:13 - Testar a criação de uma venda com o ReqBin
  • 23:17 - Rota para ler todas as vendas
  • 26:26 - Atualizar uma venda pelo id
  • 28:45 - Excluir uma venda e conferir o banco vazio

Trechos do vídeo:

  • A senha do banco só é mostrada uma vez na tela de conexão do MongoDB: copie e guarde, porque sem ela não é possível conectar ao banco.
  • Conectar e gravar no banco levam tempo: por isso usam await, que só funciona dentro de função async, e o try e catch trata o erro quando o link está errado ou não há autorização.
  • Se a conexão com o MongoDB não funciona, confira o Network Access: é preciso liberar todos os IPs ou só o seu.
  • Sem o express.json() antes das rotas, o corpo da requisição não chega como JSON e fica difícil de ler no código.
  • O findByIdAndUpdate devolve por padrão o item antes da alteração; para receber o item já alterado, passe new: true.

Hashtag Treinamentos

Para acessar publicações de JavaScript, clique aqui!


Quer aprender mais sobre JavaScript com um minicurso básico gratuito?

Posts mais recentes de JavaScript

Posts mais recentes da Hashtag Treinamentos

Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.