RESTful & Thunder Client Back-End I

Técnico em Desenvolvimento de Sistemas

Aula 6: Desenvolvimento Back-End • Express.js Framework

Guia Prático: Arquitetura RESTful & Testes com Express.js e Thunder Client

Aprenda a semântica dos verbos HTTP, convenções de URLs limpas e como construir, depurar e testar endpoints de APIs profissionais na prática.

Padrão
RESTful
Recursos limpos e sem verbos
Protocolo
HTTP/1.1
GET, POST, PUT, DELETE
Servidor
Express.js
Node.js Middleware & Rotas
Testes
Thunder Client
Extensão leve no VS Code
Fundamento Arquitetural

O Padrão RESTful e a Regra de Ouro

REST (Representational State Transfer) não é uma linguagem ou biblioteca, mas um conjunto de restrições arquiteturais que tornam as APIs previsíveis, escaláveis e universais.

1. A Web é Baseada em Recursos

No mundo REST, tudo o que o seu sistema gerencia é considerado um Recurso. Recursos são substantivos no plural que representam entidades do seu banco de dados ou domínio de negócio.

/produtos → Recurso coleção de produtos
/alunos → Recurso coleção de alunos
/turmas → Recurso coleção de turmas

2. A Regra de Ouro de Nomenclatura

URLs NUNCA devem conter verbos! A ação que será executada (cadastrar, buscar, atualizar, deletar) NÃO pertence à URL, e sim ao Verbo HTTP da requisição.

Incorreto (Anti-pattern)
POST /cadastrarProduto
O verbo "cadastrar" polui a URL.
Correto (RESTful)
POST /produtos
A ação é POST, o recurso é /produtos.

Como pensar numa Requisição RESTful:

1. Quem faz a ação?
Verbo HTTP

Define o comportamento (GET, POST, PUT, DELETE).

2. Sobre o quê?
URI do Recurso

Identifica o substantivo (/produtos, /produtos/1).

Resultado Esperado
API Semântica

Qualquer cliente no mundo entende a intenção.

Ações Fundamentais

Os 4 Verbos HTTP em Ação no Express.js

Explore cada método HTTP, veja o código no servidor Express e como configurar os testes no Thunder Client.

GET (Buscar/Listar) Status: 200 OK

Solicitar e Ler Dados

Utilizado exclusivamente para solicitar e consultar dados do servidor. É uma operação segura e idempotente: executá-la uma ou cem vezes não deve alterar o estado interno do banco de dados.

Coleção completa: GET /produtos retorna todos os produtos.
Item específico: GET /produtos/:id usa req.params para filtrar por ID.
Corpo da Requisição: Requisições GET NUNCA devem conter corpo JSON (Body).

Como Testar no Thunder Client:

  1. Selecione o método GET no dropdown.
  2. Cole a URL: http://localhost:3000/produtos.
  3. Deixe a aba Body desmarcada/vazia.
  4. Clique em Send e aguarde o status 200 OK.
server.js (Rotas GET)
Foco Linha por Linha
// 1. Rota para Listar todos os Produtos (Coleção)
app.get('/produtos', (req, res) => {
  // Retorna HTTP Status 200 OK com o array de produtos em formato JSON
  return res.status(200).json(produtos);
});

// 2. Rota para Buscar um Produto específico pelo ID (Parâmetro de Rota)
app.get('/produtos/:id', (req, res) => {
  const { id } = req.params; // Extrai o ID da URL
  
  // Procura o produto no array em memória
  const produto = produtos.find(p => p.id === parseInt(id));

  // Caso o produto não exista, retorna 404 Not Found
  if (!produto) {
    return res.status(404).json({ mensagem: 'Produto não encontrado.' });
  }

  // Se existir, retorna 200 OK com os dados do produto encontrado
  return res.status(200).json(produto);
});
POST (Criar/Cadastrar) Status: 201 Created

Enviar Novos Dados ao Servidor

Envia dados para serem processados e criados no servidor. O padrão RESTful especifica que a criação bem-sucedida de um novo recurso deve responder com o status 201 Created.

Middleware Obrigatório: Você DEVE declarar app.use(express.json()) no início do seu código para que o Express consiga ler o req.body.
URL Semântica: A rota é sempre a coleção no plural (POST /produtos).

Como Testar no Thunder Client:

  1. Selecione o método POST.
  2. URL: http://localhost:3000/produtos.
  3. Clique na aba Body e selecione a opção JSON.
  4. Envie o corpo: {"nome": "Teclado", "preco": 250.00}.
  5. Clique em Send e receba status 201 Created.
server.js (Rota POST)
Foco Linha por Linha
// OBRIGATÓRIO: Habilitar o parser de corpo JSON no Express
app.use(express.json());

// Rota para Cadastrar um Novo Produto
app.post('/produtos', (req, res) => {
  // Extrai as informações enviadas pelo cliente no corpo (body) da requisição
  const { nome, preco } = req.body;

  // Validação simples dos dados recebidos
  if (!nome || preco === undefined) {
    return res.status(400).json({ mensagem: 'Nome e Preço são obrigatórios.' });
  }

  // Criação do novo registro com identificador único incremental
  const novoProduto = {
    id: produtos.length > 0 ? produtos[produtos.length - 1].id + 1 : 1,
    nome,
    preco: Number(preco)
  };

  produtos.push(novoProduto);

  // RESTful: Retorna HTTP Status 201 Created + Objeto Criado
  return res.status(201).json({
    mensagem: 'Produto cadastrado com sucesso!',
    produto: novoProduto
  });
});
PUT (Atualizar/Substituir) Status: 200 OK

Atualização Completa de Recurso

Utilizado para substituir ou atualizar todos os dados de um item existente. A mágica do PUT no Express reside na combinação de dois canais de dados simultâneos:

1. `req.params.id` (URL): Identifica qual produto específico será atualizado (ex: /produtos/1).
2. `req.body` (JSON): Contém os novos valores a serem gravados no registro.

Como Testar no Thunder Client:

  1. Selecione o método PUT.
  2. URL com ID: http://localhost:3000/produtos/1.
  3. Na aba Body > JSON, envie os novos dados: {"nome": "Teclado RGB Pro", "preco": 299.90}.
  4. Clique em Send e receba 200 OK com os dados atualizados.
server.js (Rota PUT)
Foco Linha por Linha
// Rota para Atualizar um Produto Existente
app.put('/produtos/:id', (req, res) => {
  const { id } = req.params;             // ID na URL
  const { nome, preco } = req.body;      // Novos dados no Body

  // Localiza a posição do produto no array
  const index = produtos.findIndex(p => p.id === parseInt(id));

  // Caso o produto não exista no banco/memória
  if (index === -1) {
    return res.status(404).json({ mensagem: 'Produto não encontrado para atualização.' });
  }

  // Atualiza os dados mantendo o ID original
  produtos[index] = {
    ...produtos[index],
    nome: nome || produtos[index].nome,
    preco: preco !== undefined ? Number(preco) : produtos[index].preco
  };

  // Retorna HTTP Status 200 OK com o registro atualizado
  return res.status(200).json({
    mensagem: 'Produto atualizado com sucesso!',
    produto: produtos[index]
  });
});
DELETE (Remover) Status: 200 OK ou 204 No Content

Excluir um Recurso Específico

Utilizado para remover permanentemente um registro do servidor. Informa-se o ID do recurso a ser removido diretamente no Path da URL.

Sem Body: Não necessita de envio de corpo JSON na requisição.
Tratamento de 404: Se o ID informado não existir mais, retorne 404 Not Found.

Como Testar no Thunder Client:

  1. Selecione o método DELETE.
  2. URL com ID: http://localhost:3000/produtos/1.
  3. Não envie corpo JSON.
  4. Clique em Send e confirme a remoção. Se enviar novamente para o mesmo ID, o servidor retornará 404 Not Found!
server.js (Rota DELETE)
Foco Linha por Linha
// Rota para Deletar um Produto pelo ID
app.delete('/produtos/:id', (req, res) => {
  const { id } = req.params;

  // Encontra a posição do item
  const index = produtos.findIndex(p => p.id === parseInt(id));

  // Se não existir, retorna 404 Not Found
  if (index === -1) {
    return res.status(404).json({ mensagem: 'Produto não encontrado para exclusão.' });
  }

  // Remove o elemento do array em memória
  produtos.splice(index, 1);

  // Retorna HTTP Status 200 OK com mensagem de confirmação
  return res.status(200).json({
    mensagem: `Produto com ID ${id} removido com sucesso!`
  });
});
Simulador Interativo

Thunder Client Live Mockup

Experimente a interface idêntica à extensão do Thunder Client no VS Code. Clique em "Enviar" para testar o método selecionado na aba ativa!

Thunder Client • VS Code Extension Simulator
Ambiente: Localhost:3000
GET
Request Config
Body (JSON)
Requisições GET e DELETE não requerem corpo JSON.
Response Body
-- ms -- B
Clique no botão "Enviar" acima para testar este endpoint em tempo real.
Atividades de Fixação

Anexo: Lista de Exercícios Práticos

Desafios para consolidar os conceitos aprendidos em sala. Refatore URLs, implemente a API em memória e teste todas as rotas no Thunder Client.

Exercício 1

Tabela de Refatoração Semântica de URLs

Identifique as rotas com anti-patterns e visualize a conversão para o padrão RESTful correto.

Objetivo / Ação Rota Incorreta (Anti-pattern) Rota RESTful Correta Justificativa & Semântica
Exercício 2

Roteiro de Construção: API /alunos

Construa um CRUD completo em memória para o recurso /alunos contendo os campos nome, matricula e curso. Marque cada etapa concluída:

Seu Progresso: 0 de 6 concluídos (0%)
Exercício 3

Roteiro de Testes: Thunder Client

Sequência exata de requisições que você deve disparar no Thunder Client para homologar a API:

GET /alunos
Espera 200 (Array)
POST /alunos
Espera 201 Created
PUT /alunos/1
Espera 200 OK
DELETE /alunos/2
Espera 200 OK
GET /alunos/999
Espera 404 Not Found
Dica Prática: Testar o status de erro 404 para IDs que não existem é tão importante quanto testar o caminho feliz!
Exercício 4 • Desafio Avançado

Modelagem de Sub-recursos: Adicionar Notas por Aluno

Crie uma rota para adicionar uma nota a um aluno específico: POST /alunos/:id/notas. O corpo da requisição deve receber { "disciplina": "Back-End I", "valor": 9.5 } e o aluno deve conter um array interno notas: [].

Desafio em Sala: Apresente ao Professor!
Atividade Prática Avaliativa Individual

32 Exercícios Práticos (1 para Cada Aluno)

Cada estudante possui um tema exclusivo de negócio. Localize o número da sua chamada na lista abaixo ou pesquise pelo seu domínio para visualizar seus requisitos, atributos, rotas e payloads para o Thunder Client.

Clique no seu número de chamada para selecionar:
Aluno Nº 01 Biblioteca Municipal

POST /livros

Desenvolva uma API para gerenciamento do catálogo de livros da biblioteca municipal.

Atributos do Recurso:

Campo Tipo Descrição

Rotas Obrigatórias a Implementar:

Desafio de Sub-recurso:
POST /livros/:id/emprestimos

Registrar um empréstimo do livro com nome do leitor e data de devolução prevista.

Payloads Prontos para o Thunder Client:

Cole na aba Body > JSON do Thunder Client:
{
  "titulo": "O Guia do Mochileiro das Galáxias",
  "autor": "Douglas Adams",
  "anoPublicacao": 1979,
  "paginas": 208
}
Como testar: No Thunder Client, selecione o método correspondente, configure a URL local (http://localhost:3000/livros), cole o JSON acima e clique em Send.