Aprenda a criar um backend completo com o nosso minicurso de NodeJS! Crie sua Web API do zero e configure seu servidor backend com JavaScript.
Ao longo deste minicurso, você verá desde conceitos mais teóricos do JavaScript até a prática, para que você domine o que é uma API, uma Web API, o gerenciador de pacotes do Node e muito mais.
Tudo isso para que, ao final, você consiga ter seu backend em JavaScript completo para o seu site ou aplicação.
Aulas Disponíveis:
- Aula 1 – Crie um Backend com JavaScript
- Aula 2 – Construindo uma Web API – Requisições HTTP
- Aula 3 – Construindo uma WebAPI – Códigos de Status HTTP
- Aula 4 – Construindo uma WebAPI – Requisição do tipo PUT
- Aula 5 – Construindo uma WebAPI – Métodos POST e DELETE
- Aula 6 – Construindo uma WebAPI – Tratamento de Erros
Minicurso de NodeJS – Aula 1 – Crie um Backend com JavaScript
Vamos iniciar o nosso minicurso de NodeJS para desenvolver um sistema backend com JavaScript!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Na primeira aula do nosso minicurso de NodeJS, quero apresentar alguns conceitos teóricos importantíssimos que você precisa aprender para compreender melhor o projeto que iremos desenvolver.
Esta será uma aula um pouco mais teórica, onde abordaremos objetos no JavaScript, variáveis, API, Web API, pacotes do Node, Type module e muito mais.
Com esta aula, você terá toda a base para compreender o nosso minicurso e, ao final, conseguirá criar um backend com JavaScript capaz de fornecer informações para o seu site ou aplicativo.
Preparativos para o Minicurso
Antes de começarmos o nosso Minicurso de NodeJS , é importante que você tenha instalado em seu computador o VS Code e o NodeJS .
Para isso, eu separei duas aulas completas para que você possa ver o passo a passo de como baixar, instalar e configurar o VS Code e o NodeJS:
Configuração Inicial do VS Code
Com o VS Code instalado, vamos criar uma pasta no nosso computador onde iremos construir e salvar nossos códigos. No meu caso, criarei uma pasta chamada minicurso-nodejs-brasileirao2024.
Em seguida, podemos abrir o VS Code, ir em File, Open Folder e selecionar a pasta que acabamos de criar.
API, Web API e Comunicação na Internet
Ao longo desse projeto, iremos trabalhar com conceitos fundamentais para o desenvolvimento de um sistema backend eficiente: API, Web API e Comunicação na Internet.
Conforme formos passando por cada um deles, eu irei te explicar melhor, mas caso queira compreender detalhadamente, temos, para cada um, uma aula explicando esses temas:
Isso porque nosso sistema será uma Web API que irá nos entregar as informações de acordo com as requisições que fizermos para ele.
Estrutura Inicial do Projeto
Para dar início ao nosso projeto, vamos criar dentro do VS Code nosso primeiro arquivo JavaScript. Basta clicar na opção New File e criar um arquivo chamado tabela.js.
Um ponto interessante ao trabalharmos com o Node.js é que os sistemas JavaScript podem ser divididos em vários arquivos JS, proporcionando uma melhor organização e manutenção dos códigos.
Variáveis em JavaScript
As variáveis em JavaScript são como caixas que armazenam dados. Esses dados podem ser de diferentes tipos, e podemos manipulá-los fazendo cálculos, comparações, atualizações e assim por diante.
Podemos identificar essa variável a partir de um nome, que utilizaremos para chamá-la sempre que necessário.
Dentro do arquivo que acabamos de criar, vamos definir uma variável chamada time, que receberá um dado do tipo texto. Sempre que declaramos um texto em JavaScript, ele precisa estar entre aspas duplas ou simples.
const time = 'fluminense';
Observe que, antes de declarar a variável, utilizei a palavra-chave const. Esse termo vem de constantes, indicando que essa é uma variável que não será posteriormente manipulada em nosso código.
Criando um Objeto no JavaScript
No entanto, não queremos representar apenas o nome do time, mas sim um conjunto de informações relacionadas a ele.
Para isso, utilizaremos os objetos no JavaScript. Eles nos permitem encapsular todo um conjunto de dados relacionados a uma mesma entidade em uma única estrutura. Dentro dela, temos campos nomeados que armazenam diferentes tipos de dados.
const time = {
nome: 'Fluminense',
sigla: 'Flu',
pontos: 0,
vitorias: 0,
empates: 0,
derrotas: 0,
golsMarcados: 0,
golsSofridos: 0,
saldoGols: 0,
};
Toda essa estrutura armazena apenas os dados do Fluminense. No entanto, no Campeonato Brasileiro, temos 20 times. Então precisamos repetir essa estrutura por 20 vezes, uma para cada time.
const time = {
nome: 'Fluminense',
sigla: 'Flu',
pontos: 0,
vitorias: 0,
empates: 0,
derrotas: 0,
golsMarcados: 0,
golsSofridos: 0,
saldoGols: 0,
};
const time2 = {
nome: 'Palmeiras',
sigla: 'Pal',
pontos: 0,
vitorias: 0,
empates: 0,
derrotas: 0,
golsMarcados: 0,
golsSofridos: 0,
saldoGols: 0,
};
No entanto, como teremos diversos elementos relacionados, ao invés de criarmos 20 objetos separados, podemos agrupá-los dentro de um array.
Array no JavaScript
O array é uma lista de informações no JavaScript que nos permite agrupar dados relacionados dentro de uma única estrutura. Isso facilita o acesso e a organização desses dados.
const times = [
{
nome: "Fluminense",
sigla: "Flu",
pontos: 0,
vitorias: 0,
empates: 0,
derrotas: 0,
golsMarcados: 0,
golsSofridos: 0,
saldoGols: 0,
},
{
nome: "Palmeiras",
sigla: "Pal",
pontos: 0,
vitorias: 0,
empates: 0,
derrotas: 0,
golsMarcados: 0,
golsSofridos: 0,
saldoGols: 0,
},
];
Dessa forma, conseguimos salvar todas essas informações dentro de uma mesma “caixa”.
Isso facilita o acesso das informações, pois podemos referenciar o conteúdo desejado passando o nome do array seguido de um número que indica a posição daquele elemento na lista.
A contagem dos objetos dentro de um array começa a partir do 0. Então, no nosso exemplo, o Fluminense seria o times[0] e o Palmeiras seria o times[1].
Agora que você já entendeu a estrutura do arquivo tabela.js, você pode fazer o download do material disponível nessa aula e substituir o seu arquivo tabela.js pelo que está no material da aula.
Nesse arquivo disponível para download, você terá um array completo, com os 20 times do Campeonato Brasileiro organizados em objetos.
Criando o Arquivo Principal do Projeto
Agora que nosso arquivo tabela.js está completo, vamos criar o arquivo principal do projeto, o app.js.
Feito isso, iniciaremos um novo terminal dentro do nosso projeto. Clique em Terminal na parte superior do VS Code e, em seguida, em New Terminal.
Com o Terminal aberto, vamos inserir o comando npm init -y e apertar Enter.
Esse comando irá criar um arquivo na pasta do seu projeto chamado package.json.
Gerenciador de Pacotes do Node
O package.json é o gerenciador de pacotes do Node.js. Ele é responsável por organizar e garantir a comunicação entre as bibliotecas e os recursos externos utilizados no projeto.
Dentro desse pacote, temos as informações essenciais do projeto, como nome, versão, descrição e assim por diante.
Em “author”, você pode atribuir o seu nome entre aspas. E abaixo de “license”, vamos adicionar mais uma informação que será “type”: “module”.
{
"name": "minicurso-nodejs-brasileirao2024",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Daniel Porto",
"license": "ISC"
"type": "module"
}
A inclusão dessa informação nos permite importar recursos JavaScript entre arquivos usando a técnica de código modular.
Exportando nossa Tabela
Dentro do nosso arquivo tabela.js, vamos adicionar ao final dele, depois que o array é finalizado, o comando:
export default tabela2024;
Isso indica que qualquer outro arquivo dentro do projeto pode acessar nossa tabela2024, o array com os objetos de cada time.
Importando Informações no JavaScript
Vamos importar essa tabela dentro do nosso arquivo principal da seguinte forma:
import tabela2024 from "./tabela.js";
Assim, indicamos que queremos importar o array tabela2024 a partir do arquivo tabela.js que está na mesma pasta que nosso arquivo principal.
Instalando Framework no JavaScript – Express
A próxima etapa do nosso projeto será instalar o framework Express. Ele é um framework de aplicativo da web para Node.js, projetado para facilitar a criação de aplicativos da web e APIs.
Dentro dele, encontramos diversos recursos para nos ajudar a construir uma Web API de forma rápida e eficiente.
Para fazer essa instalação, basta abrir novamente o terminal e executar o comando:
npm install express
Feita essa instalação, você pode reparar que o nosso arquivo package.json terá uma nova informação chamada dependencies, que são as dependências instaladas no projeto.
{
"name": "minicurso-nodejs-brasileirao2024",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Daniel Porto",
"license": "ISC",
"type": "module",
"dependencies": {
"express": "^4.19.2"
}
}
Além disso, foi criado um novo arquivo chamado package-lock.json, que é similar ao package.json e é gerado automaticamente para garantir a coerência nas instalações de pacotes.
Por fim, também foi criada uma pasta chamada node_modules. Dentro dela, temos o módulo Express que acabamos de instalar e todos os outros recursos que ele precisa para funcionar corretamente.
Com isso, podemos importar esse recurso para nosso arquivo app.js.
import tabela2024 from "./tabela";
import express from 'express';
Repare que ao importar um recurso de um pacote instalado, não é necessário especificar o caminho do arquivo, apenas o nome do pacote.
Configurando um Servidor com Express – API Web
Através do Express, seremos capazes de configurar um servidor no JavaScript. O servidor é quem entregará o conteúdo solicitado por meio das requisições HTTP.
As requisições HTTP envolvem esse processo de pedido e entrega de informações e arquivos entre computadores conectados na internet.
No caso do nosso projeto, iremos construir uma API Web, que realiza esse processo de troca com base em requisições e respostas, porém ela só entrega pacotes de informações.
Essas informações podem ser utilizadas posteriormente por uma página front-end que irá puxar essas informações da nossa API Web.
Para configurar nosso servidor utilizando o Express, vamos começar criando uma variável chamada app, que será uma instância do framework Express. Essa instância será usada para configurar e gerenciar as rotas e a lógica do nosso servidor.
É nela que temos a estrutura da nossa Web API, que irá gerenciar as requisições e respostas de informações.
import tabela2024 from './tabela.js';
import express from 'express';
const app = express();
Em seguida, precisamos definir o que acontece quando algum usuário acessa o endereço principal do nosso servidor.
Para isso, utilizaremos o método app.get(). Esse método é utilizado para definir a rota HTTP GET em uma aplicação Express. Ou seja, a partir dele definimos como o servidor deve lidar com uma solicitação HTTP do tipo GET para o endereço do nosso servidor.
O primeiro argumento que esse método precisa receber é o caminho que desejamos lidar, qual a rota que estamos querendo definir. No caso, utilizaremos a / para indicar a raiz do servidor, o endereço principal.
O segundo argumento deve ser uma função de retorno, que será executada quando a solicitação GET for feita para essa rota específica. Essa função de retorno recebe dois argumentos: o objeto de requisição, que contém as informações sobre a solicitação feita, e o objeto resposta, que é usado para enviar uma resposta ao usuário.
Para enviar essa resposta, utilizaremos o método send() do objeto resposta, passando como argumento o conteúdo que deve ser enviado, no caso, nosso array tabela2024.
import tabela2024 from './tabela.js';
import express from 'express';
const app = express();
app.get('/', (requisicao, resposta) => {
resposta.send(tabela2024);
});
Feito isso, vamos utilizar o método listen do nosso objeto app para que, ao iniciar o nosso servidor, ele escute as solicitações HTTP feitas na porta especificada. Esse método recebe dois argumentos.
O primeiro é o número da porta em que o servidor irá escutar as solicitações. Iremos definir como 300, que é o mais comum, mas você pode definir qualquer porta disponível.
O segundo argumento, opcional, é a função de callback. Essa função será executada assim que o servidor estiver pronto. Nesse caso, vamos apenas utilizar a função console.log() para exibir a mensagem “Servidor rodando com sucesso”.
import tabela2024 from './tabela.js';
import express from 'express';
const app = express();
app.get('/', (requisicao, resposta) => {
resposta.send(tabela2024);
});
app.listen(300, () => console.log('servidor rodando com sucesso'));
Com isso, nosso servidor estará configurado.
Executando e Testando o Servidor
Para rodar e testar se o nosso servidor está funcionando corretamente, vamos abrir o terminal dentro do VS Code e executar o comando:
node ./app.js
Como esse é um servidor rodando localmente no nosso computador, podemos acessá-lo através do navegador pelo endereço do localhost. Basta digitar na barra de navegação localhost, seguido de dois pontos e o número da porta que desejamos interagir (http://localhost:300/).
E dentro desse endereço, teremos o nosso array, a tabela com os 20 times do Campeonato Brasileiro.
Inclusive, dentro do Chrome, temos a opção de Estilos de Formatação. Marcando essa opção, podemos visualizar melhor os nossos dados.
Além desses dois modos que o Chrome nos oferece para visualizar os dados da nossa requisição, existe também uma extensão chamada Json Viewer que, quando instalada, permite visualizar esses dados formatados, melhorando a visualização.
Minicurso de NodeJS – Aula 2 – Construindo uma Web API – Requisições HTTP
Vamos para a segunda aula do nosso minicurso de Node.js para desenvolver um sistema backend com JavaScript! Nessa aula, vou te mostrar como construir uma WebAPI.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Na segunda aula do nosso minicurso de NodeJS, vamos falar sobre WebAPI com JavaScript! Vou te explicar o que é uma requisição HTTP e quais são os tipos de requisição que nós temos.
Vou te mostrar na prática como utilizar as requisições GET, POST, PUT e DELETE. Inclusive, aplicaremos a requisição GET mais de uma vez no nosso código.
Para obter a informação de um time da nossa tabela, vamos utilizar o método find para conseguir buscar o time do qual queremos puxar as informações.
Então, faça o download do material disponível e vamos para a segunda aula do nosso curso de Backend em JavaScript.
O que é Uma Requisição HTTP
Dentro do nosso projeto, até o momento, temos uma tabela do Campeonato Brasileiro toda zerada, pois ela foi construída antes do campeonato iniciar. E no arquivo principal do backend, o app.js, estamos lendo essa tabela.
Ao ler essa tabela, estamos atendendo a uma requisição HTTP e respondendo a esse pedido.
Requisição é um sinônimo de pedido, ou seja, no caso do nosso projeto, quando é feito o pedido dos dados do Campeonato Brasileiro, nós enviamos como resposta os dados da tabela que nós temos.
Quando acessamos uma página na internet, um link, nosso navegador está fazendo uma requisição HTTP.
O HTTP (HyperText Transfer Protocol) é um padrão, um conjunto de regras que determina como funciona a comunicação na internet.
Quando você acessa um site, está na verdade enviando uma requisição (request) HTTP e recebendo do servidor uma resposta (response), o recurso com os arquivos necessários para visualizar o conteúdo da página.
Tendo recebido esses recursos, o seu navegador consegue montar a página para que você possa visualizá-la e interagir com ela.
O que veremos nesta aula será a construção de uma API Web, que é uma estrutura preparada para responder requisições HTTP, mas que por sua vez é focada em entregar dados.
Tipos de Requisição HTTP
Existem alguns tipos de requisição HTTP que podem ser feitos, e esses tipos são o que caracterizam o pedido sendo feito.
Esses tipos de requisição são chamados de métodos HTTP ou verbos HTTP. Eles são responsáveis por indicar qual ação está sendo requisitada. Existem diversos tipos, mas os principais e mais comuns são:
- GET: para obter uma informação do servidor.
- POST: para enviar e criar uma informação no servidor.
- PUT: para atualizar uma informação existente no servidor.
- DELETE: para apagar uma informação do servidor.
Os diferentes tipos de requisições HTTP facilitam a compreensão das intenções por trás das comunicações entre o cliente e o servidor. Isso nos auxilia a entender e definir os caminhos (endpoints) da API para alcançarmos funcionalidades específicas.
Por exemplo, até o momento, nossa API tem a funcionalidade de obter as informações da nossa tabela, através do método GET sendo enviado para o endpoint /.
app.get('/', (requisicao, resposta) => {
resposta.send(tabela2024);
});
Criando uma Nova Requisição – Acessando outro Endpoint
Vamos criar uma nova requisição do tipo GET, mas dessa vez, passando para ela outro endpoint.
Ao definirmos endpoints distintos na API, podemos acessar informações específicas; nesse caso, vamos acessar as informações sobre um único time.
Então, abaixo da nossa requisição que foi criada na aula anterior, vamos criar essa nova funcionalidade. Para acessar as informações de um único time, vamos usar como parâmetro a sigla dele.
Ou seja, o endpoint que iremos acessar será baseado na sigla do time fornecida pelo usuário. Essa sigla virá depois do endereço base da nossa API, o localhost:300/.
Em seguida, vamos criar uma arrow function para descrever a ação da API em relação à requisição recebida e definir a resposta enviada.
app.get('/:sigla', (requisicao, resposta) => {
});
A sigla que iremos acessar será extraída a partir do endereço que o usuário digitou. Ou seja, dentro da nossa requisição temos os campos params, que são os parâmetros da requisição, e dentro deles, temos a sigla que será extraída.
Essa sigla é o que chamamos de parâmetro de rota. Esse recurso é fundamental para acessarmos as informações corretamente.
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla;
});
Repare que esse parâmetro se chama sigla porque definimos assim no início da nossa requisição. Caso contrário, ele deveria ter o nome correspondente ao que passamos na requisição. Por exemplo, se ao invés de sigla tivéssemos utilizado abrev, ficaria assim:
app.get('/:abrev, (requisicao, resposta) => {
const abrev = requisicao.params.abrev;
});
Um ponto muito importante para obter o caminho correto à sigla informada é manter a consistência dela, seja escrita em minúscula, maiúscula ou alternando entre maiúsculas e minúsculas. É importante conseguirmos realizar a requisição corretamente.
Para isso, vamos utilizar o método toUpperCase do JavaScript para converter todo o texto do parâmetro sigla para maiúsculo. Dessa forma, independente de como o usuário informe a rota que ele deseja acessar, nós seremos capazes de atender a requisição.
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla.toUpperCase();
});
Isso é importante pois mantém a consistência na formatação do texto e a previsibilidade, facilitando a identificação do time que será acessado.
Inclusive, vamos para essa etapa da nossa requisição, identificar e encontrar o time que desejamos buscar as informações. Para isso, utilizaremos o método find do JavaScript disponível para trabalharmos com arrays.
Para esse método, vamos definir a informação que queremos encontrar, que no nosso caso será infoTime. Poderíamos atribuir o nome que quiséssemos, porém é importante definir claramente os elementos que estamos buscando para facilitar a compreensão do código.
Além da informação que está sendo buscada, precisamos estabelecer um critério que deva ser atendido para que o find encerre sua busca. Esse critério será quando a sigla do infoTime for igual a siglaInformada.
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla.toUpperCase();
const time = tabela2024.find((infoTime) => infoTime.sigla === siglaInformada);
});
Quando essa busca for concluída, vamos retornar como resposta a variável time que é o resultado do método find na nossa tabela a partir da siglaInformada.
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla.toUpperCase();
const time = tabela2024.find((infoTime) => infoTime.sigla === siglaInformada);
resposta.send(time);
});
Testando o Servidor
Para rodar e testar se o servidor está funcionando corretamente, vamos abrir o terminal dentro do VS Code e executar o comando:
node ./app.js
Com nosso servidor rodando, podemos tentar acessar uma rota determinando a sigla do time que queremos visualizar, por exemplo, o Vasco: http://localhost:300/vas
E não importa como o usuário escreva a sigla em relação a minúscula e maiúscula, pois, por causa do método toUpperCase, sempre conseguiremos entregar o resultado esperado.
Assim, conseguimos definir mais um endpoint e um recurso da nossa API.
Minicurso de NodeJS – Aula 3 – Construindo uma Web API – Códigos de Status HTTP
Chegamos à terceira aula do nosso Minicurso de NodeJS para desenvolver um sistema backend com JavaScript! Onde daremos continuidade à construção da nossa Web API.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Na terceira aula do nosso minicurso de Node.js, daremos continuidade ao assunto das requisições HTTP. Nessa aula, vou te mostrar os códigos de status HTTP (HTTP status code) e o que cada um deles significa.
Esses códigos são importantes para que você consiga compreender o que está acontecendo com a sua requisição, se ela foi feita da forma correta, se houve algum erro, ou um redirecionamento, e para lidar com cada situação.
Código de Status HTTP – HTTP Status Code
Quando fazemos uma requisição HTTP (HTTP Request), recebemos como retorna uma resposta HTTP (HTTP Response), que é a mensagem que o servidor envia ao nosso pedido.
Essa mensagem é enviada seja em caso de êxito ou em caso de fracasso. Para sinalizar o status da resposta que estamos recebendo do servidor, existem os códigos de status HTTP.
Os códigos de status HTTP (HTTP Status Codes) são responsáveis por informar o usuário sobre a situação da requisição feita por ele. São códigos que acompanham a resposta do servidor, consistem em três dígitos e são divididos em algumas categorias (famílias).
Códigos de Status HTTP – 1XX
A primeira família de códigos de status HTTP é a família 1XX. Os códigos dessa família são códigos informacionais, retornam apenas informações para o seu navegador a respeito da requisição feita.
Códigos de Status HTTP – 2XX
A família dos códigos 2XX são códigos de status HTTP que indicam respostas bem-sucedidas. Eles sinalizam que a requisição foi processada com sucesso.
Existem diversos códigos pertencentes à família 2XX que podem ser recebidos, como o código 200. Esses códigos indicam que o servidor conseguiu atender ao pedido feito e está enviando a resposta corretamente.
Códigos de Status HTTP – 3XX
Os códigos de Status HTTP da família 3XX, são códigos de redirecionamento. Quando a resposta da requisição não está exatamente onde foi solicitada, mas o servidor possui aquele conteúdo.
Isso pode ocorrer quando o endereço foi alterado permanentemente ou quando há mais de uma resposta possível para a requisição.
Códigos de Status HTTP – 4XX
Os códigos da família 4XX são códigos de status HTTP que retornam respostas de erro ao usuário. Esses códigos são gerados quando a causa do erro provém do lado do cliente, e não do servidor.
Por exemplo, o usuário digitou algum endereço errado para uma página dentro de um site, ele receberá o famoso erro 404 de página não encontrada.
Códigos de Status HTTP – 5XX
Assim como a família dos códigos 4XX retornam erros por parte do usuário. A família de códigos 5XX são códigos de status HTTP que retornam respostas de erros provenientes do lado do servidor.
Houve um problema no servidor que impediu a requisição de ser concluída corretamente.
Solicitação Inexistente no Sistema – Como Resolver
Agora que já compreendemos como funcionam os códigos de status HTTP, vamos voltar para o nosso sistema e executá-lo.
Dentro da nossa API, só temos os 20 times presentes na Série A do Campeonato Brasileiro de 2024. Ou seja, caso o usuário tente acessar o endereço correspondente a algum outro time, ele não receberá nada.
Por exemplo, ao buscar pela sigla do Santos, teremos apenas uma página em branco.
O ideal seria que, ao se deparar com um problema como esse, a nossa API exibisse o código de erro 404, e uma mensagem de página não encontrada. E é isso que iremos resolver agora.
Começando pelo endpoint inicial, a solicitação da tabela. Dentro da resposta enviada por essa rota, vamos definir o método .status() com o código HTTP correspondente, nesse caso o 200.
app.get('/', (requisicao, resposta) => {
resposta.status(200).send(tabela2024);
});
Agora, no segundo endpoint nós precisamos tratar de dois casos: o primeiro caso em que o usuário tenta acessar as informações de um time particular que existe na tabela e o segundo caso, quando ele tenta acessar um time que não existe.
Quando a requisição for feita com sucesso, enviaremos como resposta o status 200, assim como fizemos anteriormente.
Já para o segundo caso, vamos construir um if, verificando se o valor de time é igual a undefined. Isso porque o método find, retorna o valor de undefined quando não encontra o critério procurado.
Logo, se o usuário tentar acessar um time que não existe, o método find retornará undefined e, nesse caso, enviaremos como resposta o status 404, seguido de uma mensagem personalizada.
E por fim, após lidarmos com o usuário inserindo um time que não existe, podemos adicionar uma instrução return. Ou seja, caso o time não seja encontrado, a função atual será encerrada sem executar os demais procedimentos declarados dentro dela.
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla.toUpperCase();
const time = tabela2024.find((infoTime) => infoTime.sigla === siglaInformada);
if (time === undefined) {
resposta.status(404).send('Não existe na série A do Brasileirão um time com a sigla informada!');
return;
}
resposta.status(200).send(time);
});
Testando a API
Para rodar e testar se o servidor está funcionando corretamente, enviando a mensagem de erro adequadamente, vamos abrir o terminal dentro do VS Code e executar o comando:
node ./app.js
Com o servidor no ar, podemos acessar novamente a rota dos times, passando a sigla do Santos.
Perceba que dessa vez a mensagem de erro foi informada ao invés de termos apenas uma tela em branco.
Inclusive, se acessarmos a guia de desenvolvedor apertando a tecla F12 dentro do navegador, e irmos em Network, veremos o código de status HTTP 404 sendo exibido.
Undefined se comporta como false
Antes de finalizarmos essa aula, gostaria de fazer apenas uma pequena adaptação dentro do nosso if que retorna o código de status 404.
Ao invés de utilizarmos time === undefined, ou seja, verificarmos se time é igual a undefined, podemos apenas verificar se time é falso, adicionando o operador de negação ! antes da variável time.
Isso porque, quando utilizamos o undefined dentro de uma verificação do tipo booleana, que retorna verdadeiro (true) ou falso (false), ele se comporta como false.
Logo, verificar se time é igual a undefined, é o mesmo que !time, pois ambos retornam false.
Então, nosso código também poderia ter sido escrito da seguinte forma:
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla.toUpperCase();
const time = tabela2024.find((infoTime) => infoTime.sigla === siglaInformada);
if (!time) {
resposta.status(404).send('Não existe na série A do Brasileirão um time com a sigla informada!');
return;
}
resposta.status(200).send(time);
});
É importante conhecer essas duas variações pois você pode encontrar códigos com as duas sintaxes.
Atualização Automática com NodeJS
Para finalizar, se você estiver utilizando uma versão recente do Node.js você pode digitar o seguinte comando em seu terminal:
node --watch ./app.js
Isso iniciará a execução do nosso arquivo app.js, e toda vez que fizermos uma alteração no arquivo o Node.js irá automaticamente reiniciar a execução do arquivo, sem precisarmos fazer o processo de encerrar e reiniciar a API sempre que modificarmos o código dela.
Minicurso de NodeJS – Aula 4 – Construindo uma WebAPI – Requisição do tipo PUT
Na quarta aula do nosso Minicurso de NodeJS, vamos criar um novo endpoint com uma requisição do tipo PUT e vou te mostrar como utilizar o aplicativo Insomnia para fazer requisições para a nossa Web API!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Hoje, seguimos com a quarta aula do Minicurso de Node.js, continuando a construção da nossa Web API que fornecerá os dados da tabela do Campeonato Brasileiro de 2024.
Nesta aula, vou te mostrar como usar o aplicativo Insomnia para nos ajudar na construção e nos testes da nossa API, além de futuras APIs que você venha a desenvolver.
Além disso, vamos criar um novo endpoint para lidar com requisições do tipo PUT. Até então, só tínhamos utilizado requisições do tipo GET, mas hoje veremos como usar o tipo PUT para atualizar nossa tabela do Brasileirão 2024.
Então, abra o seu projeto e vem comigo para darmos continuidade ao nosso sistema backend com JavaScript.
Aplicativo Insomnia
O aplicativo Insomnia é uma ferramenta gratuita e útil para testar APIs baseadas em requisições HTTP.
Eu recomendo que você faça o download desse aplicativo, pois ele nos ajudará muito no desenvolvimento e no teste da nossa API, além de futuras APIs que você possa vir a desenvolver.
O Insomnia nos permite explorar uma variedade de requisições HTTP para nossa API, como GET, POST, PUT e DELETE. Diferente do navegador padrão, que só realiza requisições do tipo GET.
Para baixar o Insomnia, basta acessar o site deles aqui, e fazer o download gratuito.
Feito o download e a instalação do Insomnia, abra o seu projeto e inicie o servidor. Lembre-se de utilizar o comando node –watch ./app.js para que ao alterarmos o código, o Node.js reinicie automaticamente e aplique as alterações que foram feitas.
Com nossa API sendo executada, vamos ver como funciona o Insomnia. Dentro dele, clique no sinal de mais (+) e depois em HTTP Request.
Isso criará uma nova requisição (New Request). Dentro dela, podemos definir o tipo de requisição que estamos fazendo e para qual endereço queremos fazê-la.
Vamos definir uma requisição do tipo GET para a nossa API, para pegar a tabela inicial do Campeonato Brasileiro.
Com a requisição feita, podemos visualizar uma prévia da resposta dela abaixo, com o código da requisição e o resultado.
Assim, podemos utilizar o Insomnia para fazer as requisições e verificar o resultado de forma prática e direta.
Novo Endpoint – Requisição do tipo PUT
Agora que já entendemos o funcionamento do Insomnia, vamos partir para a criação do novo endpoint na nossa API que irá atualizar a tabela do Brasileirão.
Como queremos alterar uma informação, a requisição para esse endpoint será do tipo PUT. Vamos definir essa requisição dentro do nosso aplicativo app.js, logo abaixo da requisição que pega as informações de um time específico.
Essa requisição será responsável por atualizar as informações de um único time, então utilizaremos a sigla, assim como fizemos na aula 2 para o tipo GET.
E em seguida, vamos definir o nosso sistema de requisição (req) e resposta (res).
app.put('/:sigla', (req, res) => {
});
A sigla que iremos acessar será extraída a partir do endereço que o usuário digitou. Então, como vimos anteriormente, ela será obtida através do campo params da requisição (req).
app.put('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
});
Dentro dessa requisição, precisamos localizar o time selecionado. Para isso, utilizaremos o método find do JavaScript.
Esse método receberá a informação do time que queremos encontrar (t), tal que esse time tenha a sigla igual a siglaInformada.
app.put('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
});
Quando essa requisição for feita com sucesso, dentro da variável timeSelecionado, teremos o objeto correspondente ao time escolhido. E dentro dele, estão as informações que precisamos atualizar.
Body da Requisição – Atualizando as Informações
Dentro de uma requisição do tipo GET, quando estamos pegando uma informação da API, só precisamos passar o endereço para ela. Mas, nesse caso, como estamos fazendo uma requisição do tipo PUT, precisamos passar o corpo da requisição (body).
E é aqui que voltaremos a utilizar o Insomnia. Dentro do aplicativo, ao definirmos uma requisição do tipo PUT, podemos especificar os dados enviados no body da requisição.
É dentro desse corpo que enviaremos os campos que queremos atualizar com os valores que iremos inserir. Esses valores serão passados na forma de um JSON. Então, dentro do Insomnia, clique em Body e selecione a opção JSON.
Para que nossa API trate o corpo das requisições como um JSON, vamos utilizar o recurso express.json() do Express. Essa funcionalidade do Express permite o acesso e tratamento do corpo das requisições recebidas como um JSON.
Vamos adicionar essa instrução no início do nosso código dentro do arquivo app.js.
import tabela2024 from './tabela.js';
import express from 'express';
const app = express();
app.use(express.json());
As informações que enviaremos dentro dessa requisição devem ser passadas dentro do body no Insomnia. Essas informações são as mesmas presentes dentro da nossa tabela.js.
amos fazer um exemplo, atualizando as informações do Atlético Mineiro. No endereço da requisição, precisamos definir a sigla do time (CAM), e dentro do body passar nosso JSON com os campos e os valores que desejamos atualizar.
Repare que, dentro de um JSON, os campos (chaves) devem ser informados entre aspas. E não precisamos passar os 3 campos: vitórias, empates e derrotas. Mas somente aquele referente ao resultado do time.
Feito isso, dentro da requisição, no arquivo da nossa Web API, vamos criar uma variável chamada campos que receberá as chaves (keys) do nosso objeto req.body (o corpo da requisição).
app.put('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
const campos = Object.keys(req.body);
});
Esse procedimento gerará uma lista (array) com todas as chaves do corpo da nossa requisição. Ou seja, todas as chaves que precisam ser atualizadas na tabela do Brasileirão.
Identificando, Percorrendo e Atualizando os Campos Necessários
Depois de gerar o array com todos os campos que precisam ser atualizados, podemos percorrer cada um desses campos, acessando o valor atribuído a ele e atualizando a informação para o timeSelecionado.
Como cada campo representa uma chave do JSON enviado na requisição, podemos acessar a informação através do req.body[campo] e atribuir esse valor ao timeSelecionado[campo].
Dessa forma, a cada iteração, a variável campo será substituída por uma das chaves presentes no array.
app.put('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
const campos = Object.keys(req.body);
for (let campo of campos) {
timeSelecionado[campo] = req.body[campo];
}
});
Com a requisição sendo feita com sucesso, podemos adicionar o status da requisição dentro do nosso objeto resposta (res) junto do timeSelecionado que será enviado com as informações atualizadas.
Ou seja, ao enviar a atualização das informações, o usuário receberá como resposta o código de status HTTP e o time selecionado com as informações após a atualização.
app.put('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
const campos = Object.keys(req.body);
for (let campo of campos) {
timeSelecionado[campo] = req.body[campo];
}
res.status(200).send(timeSelecionado);
});
Testando a Requisição no Insomnia
Para testar se nossa requisição está sendo feita corretamente, podemos abrir novamente o Insomnia e realizar uma requisição do tipo PUT para a nossa API. Vamos atualizar as informações sobre o Atlético Mineiro.
Perceba que enviamos as informações que desejamos atualizar e como resposta obtemos todas as informações a respeito do Atlético Mineiro, com cada um dos campos atualizados.
Minicurso de NodeJS – Aula 5 – Construindo uma WebAPI – Métodos POST e DELETE
Vamos para a quinta aula do Minicurso de NodeJS, onde veremos como utilizar os métodos POST e DELETE para adicionar e remover informações da tabela do nosso Campeonato Brasileiro 2024.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Na nossa quinta aula do minicurso de Node.js, vamos abordar dois novos métodos HTTP: o método POST e o DELETE. Utilizaremos esses métodos para adicionar e remover informações da nossa tabela.
Para isso, teremos de criar novas requisições para a nossa API: uma para deletar uma informação e outra para adicionar uma informação.
Esses são dois métodos bastante úteis e comuns de serem utilizados para manter o controle correto da base de dados.
Método POST e DELETE
Até agora, dentro do nosso projeto, já trabalhamos com os métodos GET e PUT. Nesta aula, veremos como utilizar os métodos POST e DELETE.
Optei por deixar esses dois métodos por último porque, dentro do contexto em que estamos trabalhando, não faz muito sentido adicionar ou deletar um novo time na tabela do Campeonato Brasileiro de 2024.
No entanto, pensando em uma API ou um sistema que gerencia dados, esses dois métodos são muito utilizados para o controle das informações presentes, como, por exemplo, em um sistema de controle de estoque.
Inserindo uma Nova Informação – Método POST
Vamos começar pelo método POST. Para isso, precisamos definir o caminho para a construção de uma nova informação. Utilizaremos uma requisição do tipo POST para o caminho raiz do nosso servidor, a rota ‘/’.
Essa requisição, que adicionará uma nova informação à nossa tabela, executará uma função callback que, como já vimos, recebe dois parâmetros:
- req: O objeto de requisição que contém informações sobre a requisição HTTP recebida, incluindo dados enviados pelo cliente.
- res: O objeto de resposta que será utilizado para enviar uma resposta de volta ao cliente.
app.post('/', (req, res) => {
});
Dentro da função callback, a primeira coisa que faremos é extrair os dados do corpo da requisição (req.body). Esses dados são os campos e valores enviados pelo usuário do time que será inserido.
Como vimos anteriormente para o método PUT, esses dados serão passados na forma de um JSON e iremos armazená-los na constante novoTime.
app.post('/', (req, res) => {
const novoTime = req.body;
});
Em seguida, adicionaremos esses dados à nossa tabela utilizando o método push, que irá adicionar novoTime ao final do nosso array, a tabela do Campeonato Brasileiro 2024.
app.post('/', (req, res) => {
const novoTime = req.body;
tabela2024.push(novoTime);
});
Feito isso, podemos definir o código de status HTTP da resposta como 200, indicando que a requisição foi bem-sucedida, e enviar o objeto novoTime como resposta ao cliente. Isso permite ao usuário visualizar os dados do time que ele enviou.
app.post('/', (req, res) => {
const novoTime = req.body;
tabela2024.push(novoTime);
res.status(200).send(novoTime);
});
Feito isso, nossa requisição que adiciona um time à tabela foi criada.
Removendo uma Informação – Método DELETE
Com o método POST pronto, podemos criar nosso endpoint para a requisição do tipo DELETE. Essa requisição, diferente da do tipo POST, receberá além do caminho raiz, a sigla do time que será deletado.
Essa requisição também executará uma função callback e receberá os parâmetros req e res.
app.delete('/:sigla', (req, res) => {
});
Dentro da função, a primeira coisa que faremos será extrair a sigla do time que queremos remover dos parâmetros da URL (req.params.sigla). Para adequar ao padrão da nossa tabela, converteremos a sigla para maiúscula. Logo após, armazenaremos na constante siglaInformada.
app.delete('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
});
Em seguida, encontraremos o índice do time que queremos remover na tabela utilizando o método findIndex. Esse método nos permitirá buscar pelo time na tabela onde a sigla corresponda à sigla informada na requisição.
app.delete('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const indiceTimeSelecionado = tabela2024.findIndex(
(t) => t.sigla === siglaInformada
);
});
Depois de localizarmos o time pelo índice, podemos removê-lo da tabela utilizando o método splice. Esse método remove um elemento do array com base no índice especificado.
Como argumento para esse método, precisamos informar o índice que estamos buscando e quantos elementos, a partir desse selecionado, queremos remover. Como só queremos remover um time, passaremos 1 como segundo argumento.
app.delete('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const indiceTimeSelecionado = tabela2024.findIndex(
(t) => t.sigla === siglaInformada
);
const timeRemovido = tabela2024.splice(indiceTimeSelecionado, 1);
});
Por fim, definimos o código de status 200, para uma requisição bem-sucedida, e enviamos o objeto timeRemovido como resposta ao cliente.
app.delete('/:sigla', (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const indiceTimeSelecionado = tabela2024.findIndex(
(t) => t.sigla === siglaInformada
);
const timeRemovido = tabela2024.splice(indiceTimeSelecionado, 1);
res.status(200).send(timeRemovido);
});
Com isso, temos o código responsável por remover um time da nossa tabela do Campeonato Brasileiro de 2024.
Testando as Requisições POST e DELETE
Para testar se nossas requisições estão sendo feitas corretamente, primeiro iremos executar o comando node –watch ./app.js no terminal, para que o Node.js reinicie automaticamente o servidor ao realizarmos alguma alteração.
Em seguida, abriremos o aplicativo Insomnia e realizaremos uma requisição do tipo POST para a nossa API. Lembre-se de que essa requisição precisa ser feita dentro de um JSON, com os campos informados entre aspas.
Com nossa requisição POST funcional, vamos testar a requisição do tipo DELETE. Dentro do Insomnia, vamos criar uma requisição do tipo DELETE para o endereço com a rota do time do Santos, para removermos o time que acabamos de adicionar e manter a tabela em ordem.
A requisição do tipo DELETE, além de remover um time específico da nossa tabela, também retorna como resposta os dados desse time que foram removidos.
Com a aula de hoje, você aprendeu os últimos métodos fundamentais que podemos utilizar em nossa API, somando aos métodos GET e PUT, os métodos POST e DELETE.
Minicurso de NodeJS – Aula 6 – Tratamento de Erros
Chegamos à nossa sexta e última aula do Minicurso de Node.js, onde abordaremos o tratamento de erros na API para garantir o correto funcionamento do sistema.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:
Na sexta e última aula do Minicurso de Node.js, vamos abordar o tratamento de erros na API para garantir que tudo esteja funcionando corretamente.
Vou demonstrar como podemos ajustar nossa Web API para lidar com possíveis erros, como quando o usuário tenta inserir ou atualizar informações de um time que não existe em nossa base de dados.
Faremos uso da biblioteca Joi para validar os dados de entrada do usuário, estabelecer regras e enviar mensagens de erro caso o usuário insira dados inválidos.
Executando a API
O primeiro passo para iniciarmos esta aula será colocar nossa API Web para rodar. Então, vamos abrir o VS Code e executar o comando node –watch ./app.js no terminal.
Com o servidor rodando com sucesso, podemos prosseguir para o tratamento dos possíveis erros que podemos encontrar em nossa API.
Erro no Método GET – Time Não Encontrado
Na terceira aula do nosso minicurso, eu te mostrei como lidar com o erro no método GET quando o usuário tenta acessar o endereço correspondente a um time que não está registrado na nossa base de dados.
Durante a aula, utilizamos o método find para buscar pelo time solicitado. E definimos que, nos casos em que o time não fosse encontrado (!time), a nossa API retornaria o status 404 com a mensagem: “Não existe na série A do Brasileirão um time com a sigla informada!”
app.get('/:sigla', (requisicao, resposta) => {
const siglaInformada = requisicao.params.sigla.toUpperCase();
const time = tabela2024.find((infoTime) => infoTime.sigla === siglaInformada);
if (!time /*time === undefined*/) {
//undefined -> se comporta como falso toda vez que exigimos comportamento
//de boolean. -> se a variável time for "undefined", então ela vai se comportar como
//false -> Consequentemente, !time vai se comportar como verdadeiro.
resposta
.status(404)
.send(
'Não existe na série A do Brasileirão um time com a sigla informada!'
);
return;
}
resposta.status(200).send(time);
});
Podemos aplicar a mesma lógica que construímos para esse método para corrigir possíveis erros no método PUT.
Erro no Método PUT – Atualizar um Time
Assim como fizemos com o método GET, podemos construir uma validação semelhante para o método PUT, pois ele também busca pelo time que desejamos validar as informações utilizando o método find.
Então, basta adaptarmos a nossa requisição do tipo PUT para retornar o mesmo status 404 e a resposta de erro quando o time não for encontrado.
app.put("/:sigla", (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
if (!timeSelecionado) {
res
.status(404)
.send(
"Não existe na série A do Brasileirão um time com a sigla informada!"
);
return;
}
const campos = Object.keys(req.body);
for (let campo of campos) {
timeSelecionado[campo] = req.body[campo];
}
res.status(200).send(timeSelecionado);
});
Perceba que só foi preciso adaptar os nomes das variáveis e parâmetros, mas a estrutura para quando o time não é encontrado é a mesma.
Erro no Método DELETE – Removendo Time da Tabela
Na aula passada, aprendemos como criar uma requisição utilizando o método DELETE. No entanto, não testamos o que acontece se tentarmos deletar um time que não existe na nossa tabela. É isso que quero te mostrar agora.
Para isso, vamos adicionar uma instrução console.log() dentro do método DELETE para visualizarmos o índice do time selecionado quando tentamos deletar um time que não existe no banco de dados.
app.delete("/:sigla", (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const indiceTimeSelecionado = tabela2024.findIndex(
(t) => t.sigla === siglaInformada
);
console.log(indiceTimeSelecionado);
const timeRemovido = tabela2024.splice(indiceTimeSelecionado, 1);
res.status(200).send(timeRemovido);
});
Para fazer a requisição, vamos abrir o Insomnia e criar uma requisição do tipo DELETE para o endereço com a rota do Botafogo de São Paulo (BSP).
Repare que ao fazer a nossa requisição, recebemos como resposta os dados do Vitória. Se verificarmos nossa tabela agora, veremos que o time do Vitória não estará presente.
Para entender o porquê isso aconteceu, vamos dar uma olhada no terminal dentro do VS Code.
Veja que temos o valor de -1 sendo exibido no terminal. Isso significa que, ao não encontrar o time solicitado para o método DELETE, o valor atribuído à variável indiceTimeSelecionado foi -1.
Os índices negativos são utilizados para pegar o elemento dentro de um array começando pelo final. Então, ao buscar o time pelo índice -1, o Vitória (último time na tabela) foi deletado.
Para tratar os casos em que o time não foi encontrado, basta verificarmos e lidarmos com os casos em que o indiceTimeSelecionado possui o valor de -1.
app.delete("/:sigla", (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const indiceTimeSelecionado = tabela2024.findIndex(
(t) => t.sigla === siglaInformada
);
if (indiceTimeSelecionado === -1) {
res
.status(404)
.send(
"Não existe na série A do Brasileirão um time com a sigla informada!"
);
return;
}
const timeRemovido = tabela2024.splice(indiceTimeSelecionado, 1);
res.status(200).send(timeRemovido);
});
Dessa forma, ao tentarmos remover um time que não consta na tabela, ao invés do último time ser removido, enviaremos para o usuário a nossa mensagem de erro.
Instalação Joi – Validações
Até o momento, tratamos os casos em que o time não é encontrado em nossa base de dados.
No entanto, dentro da requisição do tipo PUT, precisamos considerar os casos em que o usuário fará a requisição para um time existente, mas enviará informações para campos que não existem.
Para lidar com esses casos, vamos utilizar o pacote Joi. Para instalá-lo, basta encerrarmos o servidor dentro do terminal do VS Code, pressionando as teclas Ctrl + C, e digitar o seguinte comando: npm install joi
Com a instalação concluída, vamos criar nosso arquivo de validação chamado validacao.js, onde definiremos os modelos aceitos para a nossa requisição.
Arquivo de Validação com Joi
Dentro do nosso arquivo de validação, vamos importar o pacote Joi.
import Joi from "joi";
Feito isso, vamos definir o nosso primeiro modelo de validação, que será o modelo com os dados do time.
Para definir um modelo de validação com a biblioteca Joi, utilizamos o método object(). Esse método recebe como argumento um objeto em que as chaves são os nomes das propriedades esperadas (os campos dos times) e os valores são as validações desejadas.
Vamos definir as seguintes validações:
- nome: Deve ser um texto (string) com no mínimo 4 caracteres (min(4)) e é obrigatório (required).
- sigla: Deve ser um texto (string) com exatamente 3 caracteres (length(3)) e é obrigatória (required).
- pontos: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
- vitorias: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
- empates: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
- derrotas: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
- golsMarcados: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
- golsSofridos: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
- saldoGols: Deve ser um número (number) e tem um valor padrão de 0 (default(0)).
Observe que, os campos com valor default(0) podem receber outros valores numéricos, mas caso o usuário não informe nenhum valor para eles, por padrão será enviado o valor 0.
Como queremos exportar esse modelo para o restante do nosso código, vamos adicionar a palavra-chave export na definição desse modelo.
import Joi from "joi";
export const modeloTime = Joi.object({
nome: Joi.string().min(4).required(),
sigla: Joi.string().length(3).required(),
pontos: Joi.number().default(0),
vitorias: Joi.number().default(0),
empates: Joi.number().default(0),
derrotas: Joi.number().default(0),
golsMarcados: Joi.number().default(0),
golsSofridos: Joi.number().default(0),
saldoGols: Joi.number().default(0),
});
Agora podemos criar o modelo para atualização das informações do time. Esse modelo será bem similar ao modeloTime, com a diferença de que não terá campos obrigatórios ou valores padrões.
No entanto, vamos adicionar ao final do modelo o método min(1), indicando que pelo menos um campo desse objeto precisa ser preenchido e enviado para atualizar os dados.
export const modeloAtualizacaoTime = Joi.object({
nome: Joi.string().min(4),
sigla: Joi.string().length(3),
pontos: Joi.number().min(0),
vitorias: Joi.number().min(0),
empates: Joi.number().min(0),
derrotas: Joi.number().min(0),
golsMarcados: Joi.number().min(0),
golsSofridos: Joi.number().min(0),
saldoGols: Joi.number().min(0),
}).min(1);
Feito isso, temos os nossos dois modelos de validação prontos para serem utilizados.
Validação das Informações com Base no Modelo
O primeiro passo para utilizar nossos modelos de validação é importá-los dentro do arquivo app.js.
import tabela2024 from "./tabela.js";
import express from "express";
import { modeloTime, modeloAtualizacaoTime } from "./validacao.js";
Agora, dentro do nosso PUT vamos criar a variável resultadoAvaliacao que utilizará o método validate do Joi para validar o corpo da requisição (req.body) com base no modeloAtualizacaoTime.
Para visualizar a resposta dessa validação, vamos exibi-la dentro do terminal do VS Code utilizando o console.log().
app.put("/:sigla", (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
if (!timeSelecionado) {
res
.status(404)
.send(
"Não existe na série A do Brasileirão um time com a sigla informada!"
);
return;
}
const resultadoAvaliacao = modeloAtualizacaoTime.validate(req.body);
console.log(resultadoAvaliacao);
const campos = Object.keys(req.body);
for (let campo of campos) {
timeSelecionado[campo] = req.body[campo];
}
res.status(200).send(timeSelecionado);
});
Vamos colocar nosso servidor para rodar novamente e, dentro do Insomnia, testar essa validação.
Primeiro enviaremos as informações corretamente para atualizar os dados do Atlético Mineiro.
Perceba que como resposta obtivemos todas as informações a respeito do Atlético Mineiro, com cada um dos campos atualizados.
Dentro do terminal do VS Code podemos ver que, quando a validação é feita corretamente, ele só retorna um objeto com o campo value e os campos que foram modificados.
Agora vamos enviar um objeto vazio para ver o que é exibido no local.
Repare que nesse caso dentro do nosso objeto temos o campo error informando qual foi o erro obtido no processo dessa requisição.
Então, para verificar e lidar com os casos em que o usuário não está enviando a requisição corretamente, podemos verificar se existe o campo error dentro da validação.
No JavaScript podemos pegar o campo error ao mesmo tempo que o armazenamos em uma variável, declarando-o da seguinte forma:
const { error } = modeloAtualizacaoTime.validate(req.body);
Caso esse campo error exista, vamos enviar uma resposta de status 400 com o erro ocorrido.
app.put("/:sigla", (req, res) => {
const siglaInformada = req.params.sigla.toUpperCase();
const timeSelecionado = tabela2024.find((t) => t.sigla === siglaInformada);
if (!timeSelecionado) {
res
.status(404)
.send(
"Não existe na série A do Brasileirão um time com a sigla informada!"
);
return;
}
const { error } = modeloAtualizacaoTime.validate(req.body);
if (error) {
res.status(400).send(error);
return;
}
const campos = Object.keys(req.body);
for (let campo of campos) {
timeSelecionado[campo] = req.body[campo];
}
res.status(200).send(timeSelecionado);
});
Vamos testar o resultado dessa validação dentro do Insomnia.
E não somente o erro de quando enviamos uma requisição vazia, mas com isso conseguimos lidar com todos os erros possíveis de requisições que não sigam o nosso modelo definido.
Podemos fazer o mesmo procedimento para validar a inserção de um novo time à nossa tabela, mas usando o modelo modeloTime.
app.post("/", (req, res) => {
const novoTime = req.body;
const { error } = modeloTime.validate(req.body);
if (error) {
res.status(400).send(error);
return;
}
tabela2024.push(novoTime);
res.status(200).send(novoTime);
});
Testando essa validação no Insomnia veremos que ela está funcionando corretamente, assim como a anterior.
Dessa forma, concluímos o sistema de validação dos dados da nossa API.
Ajuste no Código 201
Para finalizar, vamos fazer um ajuste na nossa requisição do tipo POST. Quando obtivermos sucesso no registro de um novo time, ao invés de utilizar o status 200, vamos utilizar o código HTTP 201.
Esse código comunica que uma nova informação foi registrada com sucesso.
app.post("/", (req, res) => {
const novoTime = req.body;
const { error } = modeloTime.validate(req.body);
if (error) {
res.status(400).send(error);
return;
}
tabela2024.push(novoTime);
res.status(201).send(novoTime);
});
Com esse último ajuste, concluímos a nossa Web API que gerencia a tabela do Campeonato Brasileiro de 2024.
Conclusão – Minicurso de NodeJS
Ao longo desse minicurso de NodeJS, você aprendeu como construir uma Web API desenvolvendo um servidor utilizando o JavaScript.
Abordamos desde os conceitos teóricos até a construção prática de um sistema backend utilizando o JavaScript, para que você possa ter um sistema completo para o seu site ou aplicação.
Hashtag Treinamentos
Para acessar publicações de JavaScript, clique aqui!
Expert em conteúdos da Hashtag Treinamentos. Auxilia na criação de conteúdos de variados temas voltados para aqueles que acompanham nossos canais.