Paulo Queiroz

Seu Primeiro Backend ✨

Se você já está trabalhando em seu conhecimento de HTML e CSS, talvez já tenha se aventurado um pouco em JavaScript, provavelmente está pronto para começar a criar seu primeiro backend. Neste artigo, usaremos Node.js para criar um backend simples que servirá como base para seus projetos futuros.

Quer pular a leitura e ir direto para o código? Clique aqui para ir direto à parte prática deste tutorial.

O que é um backend?

Primeiro de tudo, vamos definir o que é um backend. O backend é a parte de uma aplicação web responsável por processar dados e responder aos pedidos do frontend. É o motor que impulsiona o frontend e faz tudo funcionar. O backend é responsável por lidar com coisas como autenticação de usuários, operações com banco de dados e a lógica de negócios. Mas por que precisamos de um backend? Não podemos simplesmente construir tudo com HTML, CSS e JavaScript?

Well yes, but actually no meme

Brincadeiras à parte, as duas principais razões pelas quais precisamos de um backend são segurança e desempenho.

Segurança 🛡️

A coisa mais importante que você precisa saber sobre o motivo de precisarmos de um backend para segurança é que qualquer coisa que você carregar em um navegador pode ser vista por qualquer pessoa. Se você tiver qualquer tipo de informação sensível no navegador, saiba: isso não é seguro.

Quando um usuário cria uma conta no seu site, você precisa armazenar as informações dele em algum lugar, como um banco de dados. Você precisa de credenciais para ler e gravar dados em um banco de dados. O motivo pelo qual você não pode simplesmente enviar as informações do usuário do frontend diretamente para o banco de dados é que você teria que armazenar sua senha do banco de dados no frontend, o que permitiria que qualquer pessoa acessasse seu banco de dados como bem quisesse.

Podemos mitigar esse problema criando um backend, um programa que recebe os dados do frontend, os valida e depois os envia para o banco de dados. Seu backend terá as credenciais do banco de dados, mas os usuários não terão acesso a elas.

Desempenho 🚀

Outra razão pela qual precisamos de um backend é o desempenho. Se o seu aplicativo precisa fazer muito processamento, é melhor fazê-lo no servidor do que no cliente. O servidor geralmente é mais poderoso que o cliente, então ele pode lidar com mais processamento. Imagine alguém com um celular de 10 anos atrás, 34 abas abertas e vários aplicativos rodando em segundo plano. Se você enviar para essa pessoa uma lista com 10.000 itens e pedir para ela ordenar, o celular provavelmente vai travar. Se você fizer o mesmo em um servidor, ele provavelmente vai lidar com isso sem problemas.

Configurando o seu ambiente

Antes de começarmos a programar, precisamos configurar nosso ambiente. Hoje em dia, existem duas maneiras de configurar um ambiente de desenvolvimento: usando uma solução local ou uma plataforma na nuvem. Vou te ensinar como configurar um ambiente local, mas se você preferir usar a nuvem, recomendo o StackBlitz — ele é melhor que soluções como o Codesandbox, que exigem que você execute o código em uma VM; o StackBlitz roda a IDE diretamente no seu navegador, e faz isso de graça.

Ambiente local

Alguns dos passos a seguir podem variar dependendo do seu sistema operacional, mas a ideia geral é a mesma. Estarei usando macOS para este tutorial.

  1. Instale o Node.js: Node.js é uma ferramenta que nos permite rodar JavaScript fora de um navegador. Você pode baixá-lo no site oficial.
    • Siga as instruções no site para instalar o Node.js na sua máquina.
  2. Instale uma IDE: Você pode usar qualquer editor de texto que preferir. Eu recomendo o Visual Studio Code. Ele é gratuito, open source, e fácil de usar para iniciantes.

Criando seu primeiro Backend

Crie uma nova pasta vazia para o seu projeto em qualquer lugar do seu computador. Em seguida, abra essa pasta na sua IDE. No VS Code, você pode abrir uma pasta clicando em Arquivo > Abrir Pasta... ou clicando no botão Abrir Pasta na tela de boas-vindas.

VS Code Open Folder

Depois de abrir sua pasta na IDE, abra uma janela de terminal — você pode fazer isso clicando em Terminal > Novo Terminal no VS Code. No terminal, execute o seguinte comando para criar um novo projeto Node.js:

npm init -y

Esse comando cria um novo arquivo package.json na pasta do seu projeto. O arquivo package.json é onde você define as dependências e os scripts do seu projeto.

npm é um gerenciador de pacotes para Node.js. Ele permite que você instale e gerencie pacotes para seus projetos Node.js. Assim como importar o Font Awesome ou Bootstrap no seu HTML, você pode importar pacotes nos seus projetos Node.js. Porém, em vez de usar uma tag <link>, você instala pacotes usando npm.

Curiosidade: npm significa Node Package Manager (gerenciador de pacotes do Node).

Neste tutorial, usaremos uma framework chamada Express. O Express é uma framework web leve para Node.js que facilita a criação de servidores web. Para instalar o Express, execute o seguinte comando no terminal:

npm install express

Esse comando instala o pacote Express no seu projeto. Se você abrir o arquivo package.json, verá que o Express foi adicionado como uma dependência.

Antes de prosseguirmos, adicione uma linha ao seu arquivo package.json, logo após "version" e antes de "main":

{
  "name": "seu-app",
  "version": "1.0.0",
  "type": "module", // Adicione esta linha
}

Podemos falar sobre o campo type mais tarde, mas por enquanto, saiba que ele é necessário para o código que escreveremos.

Agora que temos o Express instalado, vamos criar um servidor web simples.

Criando um servidor web

Crie um novo arquivo na pasta do seu projeto chamado index.js. Este arquivo será o ponto de entrada para sua aplicação. No index.js, adicione o seguinte código:

import express from "express";

const app = express();
const port = 3000;

app.get("/", (req, res) => {
  res.send("Olá, Mundo!");
});

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

Esse código cria uma nova aplicação Express, define uma rota que responde com Olá, Mundo! quando você visita a URL raiz (/), e inicia um servidor que escuta na porta 3000.

Para testar, execute o seguinte comando no terminal:

node index.js

Esse comando inicia seu servidor. Se você abrir o navegador e navegar para http://localhost:3000, você deverá ver Olá, Mundo! exibido na página!

Olá, Mundo!

Parabéns! Você acabou de criar seu primeiro backend com Node.js e Express.

Entendendo o código

Vamos analisar o código que acabamos de escrever:

// Importe o pacote express que instalamos anteriormente
import express from "express";

// Crie uma nova aplicação Express
const app = express();
const port = 3000;

// Defina uma rota que responde com "Olá, Mundo!".
// Falaremos mais sobre rotas mais adiante.
app.get("/", (req, res) => {
  res.send("Olá, Mundo!");
});

// Inicie o servidor e registre uma mensagem no console
app.listen(port, () => {
  console.log(`Servidor rodando em http://localhost:${port}`);
});

// O servidor agora está rodando e ouvindo por pedidos. Ele continuará
// rodando até que você o interrompa pressionando Ctrl+C no terminal
// (ou fechando a janela do terminal).

Leia mais sobre portas aqui

Rotas

Antes de elaborarmos mais sobre o código, vamos falar sobre rotas. Uma rota é um padrão de URL que o servidor escuta. Quando um pedido é feito ao servidor, ele verifica a URL do pedido e a compara com uma rota. Se a URL corresponder a uma rota, o servidor executa o código associado a essa rota.

No navegador, você pode pensar em cada página que você pode visitar como uma rota. Por exemplo, google.com/ é uma rota, google.com/chrome é outra rota, e assim por diante.

No nosso código, definimos uma única rota que escuta pedidos para a URL raiz (/). Quando um pedido é feito para a URL raiz, o servidor responde com Olá, Mundo!.

Rotas do Frontend vs. Backend

Vale notar que, neste tutorial, estamos desenvolvendo uma API RESTful. REST é uma arquitetura de desenvolvimento backend que, entre outras coisas, separa o backend do frontend. Ele faz isso porque um servidor web, como o que estamos criando, é capaz de renderizar HTML e CSS, servir imagens, arquivos e muito mais.

Em uma API RESTful, o servidor (backend) apenas se comunica com o cliente (frontend) para trocar dados. Pense em envio de formulários, autenticação de usuários e operações com banco de dados. O servidor não se preocupa com como os dados são exibidos, apenas com como eles estão estruturados.

Métodos HTTP

A comunicação entre o servidor e o cliente é feita via HTTP. O protocolo HTTP define um conjunto de métodos que o cliente pode usar para interagir com o servidor. Os métodos mais comuns são:

  • GET: Usado para recuperar dados do servidor.
  • POST: Usado para enviar dados ao servidor.
  • PUT: Usado para atualizar dados no servidor.
  • DELETE: Usado para deletar dados do servidor.

Quando você navega em um site, seu navegador envia um pedido GET ao servidor para recuperar a página que você solicitou. Quando você envia um formulário, seu navegador envia um pedido POST ao servidor com os dados do formulário.

Métodos de Rotas

A maioria dos servidores web, incluindo o Express, permite que você defina rotas para diferentes métodos HTTP. No nosso código, usamos o método app.get() para definir uma rota que responde a pedidos GET. Você também pode usar app.post(), app.put() e app.delete() para definir rotas para outros métodos HTTP. É importante notar que podemos definir múltiplas funções para a mesma rota.

Se tivéssemos um projeto maior em que precisássemos criar e deletar usuários, poderíamos definir rotas assim:

app.get("/users", (req, res) => {
  // Obter todos os usuários
});

app.post("/users", (req, res) => {
  // Criar um novo usuário
});

Perceba como ambas as rotas têm a mesma URL (/users), mas respondem a métodos HTTP diferentes. Essa é uma prática comum em APIs RESTful.

Tornando isso útil

Já fizemos bastante até agora, mas nosso backend só consegue responder com Olá, Mundo! em uma única rota.

Vamos torná-lo um pouco mais útil criando uma API simples que retorna uma lista de alunos.

// app.get("/", ...)

const students = [
  { id: 1, name: "Alice", age: 20 },
  { id: 2, name: "Bob", age: 21 },
  { id: 3, name: "Charlie", age: 22 },
];

app.get("/students", (req, res) => {
  return res.json(students);
});

// app.listen(...)

Se você tentar navegar para http://localhost:3000/students, não verá a lista de alunos. Em vez disso, você verá uma mensagem de erro dizendo que o servidor não pode fazer o pedido GET para /students. Isso acontece porque toda vez que você faz mudanças no seu servidor, é necessário reiniciá-lo. Para evitar isso, podemos rodar o servidor com o flag --watch:

# Se o seu servidor já estiver rodando, pare-o pressionando Ctrl+C
# no terminal
node --watch index.js

Agora, quando você navegar para http://localhost:3000/students, deverá ver uma resposta JSON com a lista de alunos. Agora podemos retornar dados úteis, como arrays e objetos do nosso servidor. Legal, né?

Consumindo a API

Até agora, todos os nossos testes foram feitos no navegador. Como as APIs RESTful não devem renderizar HTML ou exibir algo no navegador, precisamos de outro método para usar nossa API. É aí que entra o frontend.

Vamos criar um arquivo HTML simples que busca a lista de alunos da nossa API.

<!doctype html>
<html lang="pt-br">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Alunos</title>
  </head>
  <body>
    <h1>Alunos</h1>
    <ul id="students">
      <!-- Alunos serão adicionados aqui -->
    </ul>

    <!-- Vamos adicionar um JavaScript para interagir com o nosso servidor -->
    <script>
      fetch("http://localhost:3000/students")
        .then((response) => response.json())
        .then((students) => {
          const studentsList = document.getElementById("students");
          for (const student of students) {
            const li = document.createElement("li");
            li.innerText = `${student.name} (${student.age})`;
            studentsList.appendChild(li);
          }
        });
    </script>
  </body>
</html>

Salve este código em um arquivo chamado index.html na mesma pasta que o seu arquivo index.js — esse arquivo poderia estar em qualquer outro lugar no seu computador, mas, para fins de organização, vamos mantê-lo na mesma pasta que o restante do nosso projeto.

Abra o arquivo no seu navegador e você verá... nada.

Isso porque o servidor está bloqueando o pedido. Este é um recurso de segurança chamado CORS (Cross-Origin Resource Sharing). Ele impede que sites façam pedidos para outros sites sem permissão. Como não estamos preocupados com outras pessoas usando nossa API, podemos desabilitar o CORS no nosso servidor.

Escreverei mais sobre CORS em um artigo futuro, onde exploraremos mais profundamente os pedidos HTTP e segurança.

Atenção: Desabilitar o CORS pode expor seu servidor a vulnerabilidades de segurança. Tenha cuidado ao fazer isso em um ambiente de produção.

Para desabilitar o CORS no Express, instale um pacote chamado cors:

npm install cors

Em seguida, importe e use o pacote cors no seu arquivo index.js:

import express from "express";
import cors from "cors";

const app = express();
const port = 3000;

app.use(cors());

// ...

Agora, se você abrir o arquivo index.html no navegador, deverá ver uma lista de alunos exibida na página. Você acabou de criar um frontend simples que consome dados da sua API!

Conclusão

Neste artigo, aprendemos como criar um backend simples com Node.js e Express. Cobrimos o básico do desenvolvimento backend, rotas, métodos HTTP e como consumir uma API a partir do frontend.

Este é apenas o começo da sua jornada no desenvolvimento backend. Há muito mais para aprender, como bancos de dados, autenticação e segurança.

Vou escrever um post dando continuidade a esse, onde mergulharemos mais fundo no desenvolvimento backend. Vamos aprender a receber dados do frontend (através de formulários, por exemplo) e como armazenar e manipular dados. Fique ligado!

P.S.: o código deste artigo está disponível em GitHub