Seja Bem-Vindo. Este site tem recursos de leitura de texto, basta marcar o texto e clicar no ícone do alto-falante   Click to listen highlighted text! Seja Bem-Vindo. Este site tem recursos de leitura de texto, basta marcar o texto e clicar no ícone do alto-falante

Linguagem e Técnica de Programação II – Aula 05

Linguagem e Técnica de Programação II – Aula 05

Backend com Node.js e Express — do servidor mínimo ao CRUD completo

Apresentação

Esta aula dá continuidade ao estudo do backend iniciado com o servidor “Hello World”. Aqui o estudante evolui do conceito de rota simples para a construção de uma API funcional com operações de Criar, Ler, Atualizar e Remover dados (CRUD) — o padrão mais comum de backend usado na indústria.

Objetivos da aula

Ao final desta aula, o estudante deve ser capaz de:

  • explicar a relação entre os métodos HTTP e as operações CRUD;
  • ler e interpretar um servidor Express com múltiplas rotas;
  • entender o papel do middleware express.json();
  • entender o uso de req.params e req.body;
  • reconhecer códigos de status HTTP (200, 201, 404) e por que eles importam;
  • (opcional) executar e testar as rotas usando um navegador ou uma ferramenta como Insomnia/Postman/Thunder Client.

Metodologia

Aula expositivo-demonstrativa, com o professor codificando ao vivo. Recomenda-se testar cada rota logo após criá-la, para que o efeito seja visível imediatamente — isso ajuda a manter a atenção de turmas mais dispersas.

Recursos necessários

  • Node.js instalado;
  • Editor de código (VS Code);
  • Extensão ou aplicativo para testar rotas (Thunder Client no VS Code, Postman, Insomnia, ou até o próprio navegador para rotas GET).

1. Relembrando o essencial

Backend é a parte do sistema que recebe requisições, processa dados e devolve respostas. Node.js permite escrever esse backend em JavaScript; Express simplifica a criação das rotas.

2. HTTP e a relação com CRUD

CRUD é a sigla para as quatro operações básicas que qualquer sistema realiza sobre dados: Create (criar), Read (ler), Update (atualizar), Delete (remover). No mundo das APIs Web, cada uma dessas operações costuma ser associada a um método HTTP:

Operação CRUD Método HTTP Finalidade
Create POST Criar um novo recurso
Read GET Ler um ou mais recursos
Update PUT Atualizar um recurso existente
Delete DELETE Remover um recurso

Explicação detalhada: essa é a convenção usada por APIs no padrão REST, e é a mais encontrada no mercado. O MDN Web Docs (Mozilla) define GET como o método usado para solicitar uma representação de um recurso, sem alterá-lo, e POST como o método usado para enviar dados a serem processados pelo servidor — geralmente criando um novo recurso.

3. Preparando o projeto

mkdir backend-alunos
cd backend-alunos
npm init -y
npm install express

Arquivo server.js (usado em todos os exemplos seguintes).

4. Middleware: o que é e por que precisamos dele agora

Middleware é uma função que “intercepta” a requisição antes dela chegar à rota final. Para que o Express consiga ler dados enviados no corpo da requisição (por exemplo, um novo aluno enviado via POST), é preciso ativar o middleware embutido express.json().

const express = require('express');
const app = express();

app.use(express.json()); // permite ler JSON enviado no corpo da requisição

app.listen(3000, () => {
  console.log('Servidor rodando em http://localhost:3000');
});

Explicação detalhada: sem essa linha, req.body chegaria undefined nas rotas POST e PUT. Esse é um erro comum e um bom ponto de atenção para a turma.

5. Nossa “base de dados” (simplificada)

Para não depender de banco de dados nesta aula, usamos um array em memória. Ele existe apenas enquanto o servidor está rodando; ao reiniciar, os dados voltam ao estado inicial. Essa limitação deve ser dita claramente aos alunos, para não gerar a falsa ideia de que isso é o que se usa em produção.

let alunos = [
  { id: 1, nome: "Maria Silva", turma: "3º Ano" },
  { id: 2, nome: "João Souza", turma: "3º Ano" }
];

6. CRUD completo — passo a passo

6.1 READ (listar todos) — GET /alunos

app.get('/alunos', (req, res) => {
  res.json(alunos);
});

Explicação: essa rota apenas devolve o array inteiro em formato JSON. É a operação mais simples do CRUD.

6.2 READ (buscar um específico) — GET /alunos/:id

app.get('/alunos/:id', (req, res) => {
  const id = Number(req.params.id);
  const aluno = alunos.find(a => a.id === id);

  if (!aluno) {
    return res.status(404).json({ erro: "Aluno não encontrado" });
  }

  res.json(aluno);
});

Explicação detalhada:

  • :id na rota é um parâmetro de rota; o valor digitado na URL fica disponível em req.params.id;
  • como tudo que vem da URL chega como texto, convertemos para número com Number(...);
  • o status 404 (Not Found) é devolvido quando o aluno não existe — devolver sempre 200 mesmo em caso de erro é uma prática ruim e vale a pena mostrar isso à turma.

6.3 CREATE — POST /alunos

app.post('/alunos', (req, res) => {
  const novoAluno = {
    id: alunos.length + 1,
    nome: req.body.nome,
    turma: req.body.turma
  };

  alunos.push(novoAluno);
  res.status(201).json(novoAluno);
});

Explicação detalhada:

  • req.body contém os dados enviados pelo cliente (graças ao middleware express.json() configurado antes);
  • o status 201 (Created) indica que um novo recurso foi criado com sucesso — diferente do 200 genérico;
  • a geração de id aqui é simplificada (length + 1), o que é aceitável para fins didáticos, mas não é seguro em sistemas reais (pode gerar IDs duplicados após exclusões). Vale comentar essa limitação com a turma.

6.4 UPDATE — PUT /alunos/:id

app.put('/alunos/:id', (req, res) => {
  const id = Number(req.params.id);
  const aluno = alunos.find(a => a.id === id);

  if (!aluno) {
    return res.status(404).json({ erro: "Aluno não encontrado" });
  }

  aluno.nome = req.body.nome;
  aluno.turma = req.body.turma;

  res.json(aluno);
});

Explicação detalhada: a lógica combina duas coisas já vistas: buscar por id (como no GET individual) e sobrescrever os dados usando req.body (como no POST).

6.5 DELETE — DELETE /alunos/:id

app.delete('/alunos/:id', (req, res) => {
  const id = Number(req.params.id);
  const existe = alunos.some(a => a.id === id);

  if (!existe) {
    return res.status(404).json({ erro: "Aluno não encontrado" });
  }

  alunos = alunos.filter(a => a.id !== id);
  res.status(204).send();
});

Explicação detalhada: o status 204 (No Content) é o padrão para exclusões bem-sucedidas — o servidor confirma a ação, mas não precisa devolver nenhum dado.

7. Arquivo completo (server.js)

const express = require('express');
const app = express();

app.use(express.json());

let alunos = [
  { id: 1, nome: "Maria Silva", turma: "3º Ano" },
  { id: 2, nome: "João Souza", turma: "3º Ano" }
];

// READ - listar todos
app.get('/alunos', (req, res) => {
  res.json(alunos);
});

// READ - buscar um
app.get('/alunos/:id', (req, res) => {
  const id = Number(req.params.id);
  const aluno = alunos.find(a => a.id === id);
  if (!aluno) return res.status(404).json({ erro: "Aluno não encontrado" });
  res.json(aluno);
});

// CREATE
app.post('/alunos', (req, res) => {
  const novoAluno = {
    id: alunos.length + 1,
    nome: req.body.nome,
    turma: req.body.turma
  };
  alunos.push(novoAluno);
  res.status(201).json(novoAluno);
});

// UPDATE
app.put('/alunos/:id', (req, res) => {
  const id = Number(req.params.id);
  const aluno = alunos.find(a => a.id === id);
  if (!aluno) return res.status(404).json({ erro: "Aluno não encontrado" });
  aluno.nome = req.body.nome;
  aluno.turma = req.body.turma;
  res.json(aluno);
});

// DELETE
app.delete('/alunos/:id', (req, res) => {
  const id = Number(req.params.id);
  const existe = alunos.some(a => a.id === id);
  if (!existe) return res.status(404).json({ erro: "Aluno não encontrado" });
  alunos = alunos.filter(a => a.id !== id);
  res.status(204).send();
});

app.listen(3000, () => {
  console.log('Servidor rodando em http://localhost:3000');
});

8. Testando as rotas

Como rotas POST, PUT e DELETE não podem ser testadas digitando a URL no navegador, é preciso uma ferramenta de teste de API. Sugestões simples: Thunder Client (extensão do VS Code) ou Postman.

Exemplos de teste:

Ação Método URL Corpo (JSON)
Listar alunos GET /alunos
Buscar aluno 1 GET /alunos/1
Criar aluno POST /alunos { "nome": "Ana", "turma": "3º Ano" }
Atualizar aluno 1 PUT /alunos/1 { "nome": "Maria Editada", "turma": "3º Ano" }
Remover aluno 2 DELETE /alunos/2

9. Exemplo extra — Middleware personalizado (log de requisições)

Além do middleware pronto (express.json()), é possível criar o próprio. Este exemplo registra no console todas as requisições recebidas:

app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

Explicação detalhada: next() é essencial — sem ele, a requisição fica “presa” nesse middleware e nunca chega até a rota. Esse exemplo é opcional, mas ajuda a mostrar visualmente, no console, cada requisição chegando ao servidor conforme a turma testa as rotas.

10. Exemplo extra — Nodemon (conveniência, não obrigatório)

Por padrão, é preciso reiniciar o servidor manualmente (Ctrl+C e node server.js de novo) a cada alteração no código. O pacote nodemon reinicia automaticamente:

npm install -D nodemon
npx nodemon server.js

Vantagens do modelo apresentado

  • reaproveita a mesma linguagem (JavaScript) já usada no front-end;
  • Express reduz drasticamente a quantidade de código necessária;
  • a lógica de CRUD é a mesma usada, em essência, em sistemas reais de mercado.

Desvantagens / limitações do exemplo didático

  • os dados não são persistidos (somem ao reiniciar o servidor) — em um sistema real, isso seria feito com um banco de dados (fora do escopo desta aula);
  • não há validação de dados nem tratamento de erros mais robusto;
  • não há autenticação — qualquer pessoa poderia chamar qualquer rota.

Encerramento

Ao final desta aula, o estudante deve reconhecer que um backend, por mais simples que seja, geralmente gira em torno das mesmas quatro operações (CRUD), mapeadas para métodos HTTP padronizados. Esse entendimento é a base para qualquer tecnologia de backend que o estudante venha a usar no futuro, independentemente da linguagem.

Referências utilizadas

  • Express (repositório oficial). Descrição do framework como minimalista e focado em rotas. Disponível em: github.com/expressjs/express.
  • Node.js (site oficial). Descrição como runtime JavaScript baseado no motor V8. Disponível em: nodejs.org.
  • MDN Web Docs (Mozilla). Definição dos métodos de requisição HTTP (GET, POST, entre outros). Disponível em: developer.mozilla.org/docs/Web/HTTP/Methods.

Fim da aula 05

Click to listen highlighted text!