Microprojeto educativo fullstack com foco em simplicidade, clareza e independência tecnológica. Aqui você encontrará múltiplas implementações de frontend e backend para um CRUD de clientes, usando apenas JavaScript puro (Node.js + JS no front) ou React, e com suporte a múltiplos bancos de dados.
UCRUD-FULLJS/
├── backend-MySQL/ # Backend com Node.js + Express + MySQL
├── backend-PostgreSQL/ # Backend com Node.js + Express + PostgreSQL
├── frontAxios/ # Frontend React usando Axios
├── frontFetch/ # Frontend React usando Fetch API
├── frontVanilla/ # Frontend HTML + CSS + JS puro (vanilla)
├── LICENSE
├── README.md
└── .gitignore
- Node.js + Express
- Banco de dados:
- PostgreSQL (via
pg) - MySQL (via
mysql2) - (MongoDB em breve)
- PostgreSQL (via
- React + Axios
- React + Fetch
- HTML + CSS + JS puro (vanilla)
Todas as versões (front e back) implementam as operações essenciais de CRUD:
| Método | Rota | Descrição |
|---|---|---|
| GET | /clientes |
Lista todos os clientes |
| GET | /clientes/:id |
Retorna cliente específico |
| POST | /clientes |
Cria um novo cliente |
| PUT | /clientes/:id |
Atualiza um cliente existente |
| DELETE | /clientes/:id |
Deleta um cliente pelo ID |
- Node.js 18+
- Banco de dados local (PostgreSQL ou MySQL)
- Ferramentas úteis:
- Postman (para testes de API)
- Insomnia
- DBeaver ou Workbench
cd backend-PostgreSQL
npm install
npm startCertifique-se de configurar corretamente os dados de conexão no src/server.js.
CREATE TABLE clientes (
id SERIAL PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
endereco VARCHAR(200),
email VARCHAR(100) NOT NULL,
telefone VARCHAR(20)
);CREATE TABLE clientes (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
endereco VARCHAR(200),
email VARCHAR(100),
telefone VARCHAR(20)
);cd frontAxios
npm install
npm run devcd frontFetch
npm install
npm run dev- Acesse
frontVanilla/index.htmldiretamente no navegador (não precisa build). - Certifique-se de que o backend está rodando em
http://localhost:3000.
{
"nome": "João Silva",
"endereco": "Rua Exemplo, 123",
"email": "[email protected]",
"telefone": "11999999999"
}Este projeto está licenciado sob os termos da MIT License.
- Demonstrar um CRUD completo com múltiplas abordagens de frontend
- Integrar backends simples com diferentes bancos de dados
- Servir como referência para aulas, bootcamps ou estudos autodidatas
Feito com 💙 por rafaellindemann
Vambora testar pelo Postman as rotas implementadas no projeto.
Este mini tutorial ensina como testar manualmente a API REST do seu backend (MySQL ou PostgreSQL) utilizando o Postman.
💡 A API deve estar rodando em
http://localhost:3000.
- Método:
GET - URL:
http://localhost:3000/clientes - Objetivo: Retorna todos os clientes cadastrados.
- Selecione o método
GET - Cole a URL acima
- Clique em Send
- Você verá uma lista de objetos
clienteno painel de resposta.
- Método:
GET - URL:
http://localhost:3000/clientes/1(substitua1pelo ID desejado) - Objetivo: Retorna os dados de um cliente específico.
- Selecione o método
GET - Insira a URL com um ID real
- Clique em Send
- Método:
POST - URL:
http://localhost:3000/clientes - Objetivo: Adiciona um novo cliente ao banco.
{
"nome": "João Silva",
"endereco": "Rua Exemplo, 123",
"email": "[email protected]",
"telefone": "11999999999"
}- Método
POST - Aba
Body→ Selecioneraw+JSON - Cole o JSON acima
- Clique em Send
- O cliente será criado, e os dados retornados na resposta.
- Método:
PUT - URL:
http://localhost:3000/clientes/1(troque o ID) - Objetivo: Atualiza os dados de um cliente.
{
"nome": "João Atualizado",
"endereco": "Rua Nova, 456",
"email": "[email protected]",
"telefone": "21999999999"
}- Método
PUT - Aba
Body→raw+JSON - Insira os dados atualizados
- Clique em Send
- Método:
DELETE - URL:
http://localhost:3000/clientes/1(substitua com o ID real) - Objetivo: Remove o cliente do banco de dados.
- Método
DELETE - Insira a URL com o ID do cliente a ser removido
- Clique em Send
- Sempre use Content-Type: application/json no cabeçalho ao enviar corpo em POST/PUT.
- Certifique-se que o backend está rodando antes de testar.
- Use
GET /clientesapós POST/PUT/DELETE para conferir se deu tudo certo.
O bloco try/catch tem a função de tratar erros que possam acontecer durante a execução da rota /clientes no backend.
Vamos detalhar:
app.get('/clientes', async (req, res) => {
try {
const [rows] = await pool.query('SELECT * FROM clientes');
res.json(rows);
} catch (err) {
console.error(err.message);
res.status(500).json({ error: 'Erro ao buscar clientes' });
}
});-
Tudo que está dentro do bloco
tryserá executado normalmente. -
Aqui, ele faz uma consulta no banco de dados:
const [rows] = await pool.query('SELECT * FROM clientes');
-
Se der tudo certo, ele retorna os dados dos clientes em JSON:
res.json(rows);
- Se a conexão com o banco falhar, a tabela não existir ou ocorrer qualquer exceção durante a execução do
await pool.query(...), o fluxo salta diretamente para o blococatch.
-
O erro capturado fica disponível na variável
err. -
O código imprime a mensagem de erro no terminal do servidor:
console.error(err.message);
-
E responde para o cliente (navegador ou frontend) com um status HTTP 500 (erro interno no servidor) e uma mensagem amigável:
res.status(500).json({ error: 'Erro ao buscar clientes' });
- Chamadas assíncronas (com
await) podem lançar exceções se algo der errado. - Sem
try/catch, o servidor quebraria a execução da rota e poderia até cair completamente, dependendo do caso. - Com
try/catch, você controla a resposta ao usuário e mantém o servidor rodando com segurança.
Resumindo:
try→ executa o código que pode falhar.catch→ intercepta o erro caso ocorra e permite tratá-lo de forma segura.- Isso evita que a aplicação quebre e melhora a experiência do usuário, que recebe uma resposta clara mesmo em caso de falhas.
O try/catch não antecipa a falha — ele deixa o erro acontecer e então intercepta e trata esse erro depois que ele ocorre.
Vamos ilustrar:
Imagine que dentro do try você tem:
const [rows] = await pool.query('SELECT * FROM clientes');Se o banco estiver fora do ar ou a tabela clientes não existir, a função pool.query(...) vai lançar uma exceção.
- Sem try/catch → o erro “estoura” e pode derrubar a rota (ou até todo o servidor, se não for tratado em nenhum lugar).
- Com try/catch → o erro acontece igual, mas é “capturado” pelo
catch, permitindo que você trate a situação de forma controlada (ex: enviar uma mensagem amigável ao usuário).
try/catchnão evita que o erro ocorra.- Ele evita que o erro não tratado quebre a aplicação.
- E permite que você defina como reagir quando o erro acontecer.
Analogia:
Pense no try como dirigir um carro e no catch como o airbag:
- O airbag não impede o acidente.
- Mas quando ele acontece, o airbag amortece e protege — evitando consequências piores.
Resumo final:
O
try/catchnão previne erros — ele trata erros depois que eles acontecem, de forma controlada e segura.
//