Fundamentos do Node.js
PROJETO: Servidor HTTP com Variáveis de Ambiente e Rotas Básicas
Aprenda sobre projeto: servidor http com variáveis de ambiente e rotas básicas
PROJETO: Servidor HTTP com Variáveis de Ambiente e Rotas Básicas
Olá, futuro desenvolvedor Node.js! 👋 Nesta aula prática, vamos colocar a mão na massa e construir nosso primeiro servidor HTTP do zero, utilizando apenas os módulos nativos do Node.js. Este projeto é fundamental para entender como as requisições e respostas funcionam em um nível mais baixo, antes de explorarmos frameworks mais complexos.
🎯 Objetivos de Aprendizagem
Ao final deste projeto, você será capaz de:
- Criar um servidor HTTP básico usando o módulo
httpdo Node.js. - Gerenciar variáveis de ambiente com
process.enve a bibliotecadotenv. - Implementar um sistema de roteamento simples para diferentes URLs.
- Enviar diferentes tipos de respostas (texto, HTML, JSON).
- Lidar com rotas não encontradas (erro 404).
- Aplicar boas práticas na configuração de projetos Node.js.
🚀 Pré-requisitos
Antes de começarmos, certifique-se de que você tem:
- Node.js e npm (ou yarn) instalados em sua máquina.
- Um editor de código de sua preferência (VS Code é altamente recomendado).
- Conhecimento básico de JavaScript.
🏗️ 1. Preparando o Ambiente do Projeto
Vamos começar criando a estrutura básica do nosso projeto.
Passo 1: Criar o Diretório do Projeto
Abra seu terminal e execute os seguintes comandos:
mkdir meu-servidor-http
cd meu-servidor-httpPasso 2: Inicializar o Projeto Node.js
Dentro do diretório meu-servidor-http, inicialize um novo projeto Node.js. Isso criará um arquivo package.json para gerenciar as dependências do seu projeto.
npm init -yO -y aceita todas as opções padrão. Sinta-se à vontade para preencher as informações manualmente se preferir.
Passo 3: Instalar a Biblioteca dotenv
Para gerenciar variáveis de ambiente de forma eficaz em desenvolvimento, usaremos a biblioteca dotenv. Ela carrega variáveis de um arquivo .env para process.env.
npm install dotenv🌐 2. Entendendo o Módulo http do Node.js
O Node.js possui um módulo nativo http que nos permite criar servidores web. Ele é a base sobre a qual frameworks como o Express.js são construídos.
http.createServer()
A função principal é http.createServer(). Ela recebe uma função de callback que será executada toda vez que uma requisição HTTP for recebida pelo servidor. Esta função de callback recebe dois argumentos:
request(req): Um objeto que contém informações sobre a requisição HTTP recebida (URL, método, cabeçalhos, etc.).response(res): Um objeto que usamos para enviar a resposta HTTP de volta ao cliente (cabeçalhos, corpo da resposta, status, etc.).
A documentação oficial do Node.js sobre o módulo http pode ser encontrada aqui.
Exemplo Básico "Hello World"
Vamos criar um arquivo index.js na raiz do seu projeto com o seguinte conteúdo:
// index.js
const http = require('http');
const server = http.createServer((req, res) => {
// Define o código de status HTTP e o cabeçalho Content-Type
res.writeHead(200, { 'Content-Type': 'text/plain' });
// Envia "Hello, World!" como corpo da resposta
res.end('Hello, World from Node.js HTTP Server!\n');
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`🚀 Servidor rodando na porta ${PORT}`);
console.log(`Acesse: http://localhost:${PORT}`);
});Para executar este servidor, vá ao seu terminal e digite:
node index.jsAbra seu navegador e acesse http://localhost:3000. Você deverá ver a mensagem "Hello, World from Node.js HTTP Server!".
🔑 3. Variáveis de Ambiente com process.env e dotenv
Variáveis de ambiente são cruciais para configurar sua aplicação de forma flexível, sem codificar informações sensíveis ou específicas do ambiente diretamente no seu código.
process.env
No Node.js, todas as variáveis de ambiente estão disponíveis através do objeto global process.env. Por exemplo, se você tem uma variável de ambiente PORT=8080, você pode acessá-la via process.env.PORT.
Usando dotenv para Desenvolvimento Local
Em produção, você define variáveis de ambiente diretamente no seu servidor. No entanto, para desenvolvimento local, é mais conveniente usar um arquivo .env. A biblioteca dotenv lê este arquivo e adiciona suas variáveis ao process.env.
Configurando dotenv
-
Crie um arquivo
.envna raiz do seu projeto (no mesmo nível depackage.jsoneindex.js).PORT=3000 NODE_ENV=development MESSAGE="Bem-vindo ao meu servidor!"Importante: Adicione
.envao seu arquivo.gitignorepara garantir que ele não seja versionado no Git, pois pode conter informações sensíveis. -
Carregue as variáveis no seu arquivo
index.js. A chamada pararequire('dotenv').config()deve ser feita o mais cedo possível na sua aplicação.
// index.js
require('dotenv').config(); // Carrega as variáveis do .env
const http = require('http');
// ... (restante do código)Agora, você pode acessar process.env.PORT, process.env.NODE_ENV, etc. no seu código.
🛠️ 4. Construindo o Servidor HTTP Completo com Rotas
Agora vamos integrar tudo o que aprendemos para criar um servidor com roteamento básico e variáveis de ambiente.
Passo 1: Configuração Inicial
Modifique seu index.js para incluir dotenv e usar a variável de ambiente PORT.
// index.js
require('dotenv').config(); // 👈 Carrega as variáveis de ambiente
const http = require('http');
const PORT = process.env.PORT || 8080; // Usa a porta do .env ou 8080 como fallback
const MESSAGE = process.env.MESSAGE || "Servidor Node.js rodando!";
// ... (restante do código será adicionado aqui)Passo 2: Criando o requestListener
Este é o coração do nosso servidor. A função de callback que http.createServer() recebe.
// index.js (continuação)
const server = http.createServer((req, res) => {
// `req.url` contém o caminho da requisição (ex: '/', '/about', '/api/users')
// `req.method` contém o método HTTP (ex: 'GET', 'POST', 'PUT', 'DELETE')
console.log(`Requisição recebida: ${req.method} ${req.url}`);
// ... (lógica de roteamento será adicionada aqui)
});
// ... (início do servidor)Passo 3: Implementando Rotas Básicas
Vamos usar uma estrutura if/else if para rotear as requisições com base em req.url.
// index.js (continuação dentro de http.createServer())
const server = http.createServer((req, res) => {
console.log(`Requisição recebida: ${req.method} ${req.url}`);
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(`<h1>${MESSAGE}</h1><p>Bem-vindo à página inicial!</p>`);
} else if (req.url === '/about') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>Sobre Nós</h1><p>Este é um servidor HTTP simples feito com Node.js.</p>');
} else if (req.url === '/api/users') {
// Exemplo de resposta JSON
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(users));
}
// ... (rota 404 será adicionada aqui)
});Passo 4: Lidando com Rotas Não Encontradas (404)
É crucial informar ao cliente quando uma rota solicitada não existe. Usamos o status HTTP 404 Not Found.
// index.js (continuação dentro de http.createServer())
const server = http.createServer((req, res) => {
console.log(`Requisição recebida: ${req.method} ${req.url}`);
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(`<h1>${MESSAGE}</h1><p>Bem-vindo à página inicial!</p>`);
} else if (req.url === '/about') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>Sobre Nós</h1><p>Este é um servidor HTTP simples feito com Node.js.</p>');
} else if (req.url === '/api/users') {
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(users));
} else {
// Rota não encontrada
res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>404 Not Found</h1><p>A página que você procura não existe.</p>');
}
});Passo 5: Iniciando o Servidor
Finalmente, inicie o servidor na porta definida e adicione uma mensagem de console para feedback.
// index.js (continuação)
server.listen(PORT, () => {
console.log(`🚀 Servidor rodando em modo ${process.env.NODE_ENV}`);
console.log(`Acesse: http://localhost:${PORT}`);
});🧑💻 5. Código Completo do Servidor (index.js)
Aqui está o código completo do seu arquivo index.js até agora:
// index.js
require('dotenv').config(); // Carrega as variáveis de ambiente do arquivo .env
const http = require('http');
// Define a porta do servidor, usando a variável de ambiente PORT ou um valor padrão (8080)
const PORT = process.env.PORT || 8080;
// Define uma mensagem de boas-vindas, usando a variável de ambiente MESSAGE ou um valor padrão
const MESSAGE = process.env.MESSAGE || "Servidor Node.js rodando!";
// Cria o servidor HTTP
const server = http.createServer((req, res) => {
// Loga cada requisição recebida para fins de depuração
console.log(`Requisição recebida: ${req.method} ${req.url}`);
// Lógica de roteamento baseada na URL da requisição
if (req.url === '/') {
// Rota para a página inicial
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); // Status 200 OK, HTML
res.end(`
<h1>${MESSAGE}</h1>
<p>Bem-vindo à página inicial do nosso servidor HTTP simples!</p>
<p>Experimente acessar <a href="/about">/about</a> ou <a href="/api/users">/api/users</a>.</p>
`);
} else if (req.url === '/about') {
// Rota para a página "Sobre Nós"
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); // Status 200 OK, HTML
res.end(`
<h1>Sobre Nós</h1>
<p>Este é um servidor HTTP simples feito com Node.js puro.</p>
<p>Ele demonstra o uso do módulo 'http', variáveis de ambiente e roteamento básico.</p>
`);
} else if (req.url === '/api/users') {
// Rota para uma API que retorna dados de usuários em formato JSON
const users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
{ id: 3, name: 'Charlie', email: 'charlie@example.com' }
];
res.writeHead(200, { 'Content-Type': 'application/json' }); // Status 200 OK, JSON
res.end(JSON.stringify(users)); // Converte o array de objetos para JSON string
} else {
// Rota para URLs não encontradas (404 Not Found)
res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' }); // Status 404 Not Found, HTML
res.end(`
<h1>404 Not Found</h1>
<p>Oops! A página que você procura não existe em nosso servidor.</p>
<p>Tente voltar para a <a href="/">página inicial</a>.</p>
`);
}
});
// Inicia o servidor e o faz escutar na porta definida
server.listen(PORT, () => {
console.log(`🚀 Servidor rodando em modo ${process.env.NODE_ENV || 'produção (sem NODE_ENV definido)'}`);
console.log(`Acesse o servidor em: http://localhost:${PORT}`);
console.log(`Variáveis de ambiente carregadas: PORT=${PORT}, MESSAGE="${MESSAGE}"`);
});▶️ 6. Executando e Testando o Projeto
-
Salve o arquivo
index.jse o arquivo.env(comPORT=3000ou outro valor) no diretóriomeu-servidor-http. -
Execute o servidor no terminal:
node index.js -
Abra seu navegador e teste as seguintes URLs:
http://localhost:3000(ou a porta que você configurou)http://localhost:3000/abouthttp://localhost:3000/api/usershttp://localhost:3000/qualquer-outra-rota(para ver o 404)
Você deverá ver as respostas correspondentes no navegador e os logs no seu terminal.
📝 7. Exercícios e Desafios
Parabéns por construir seu primeiro servidor HTTP! Agora, para solidificar seu aprendizado, aqui estão alguns desafios:
Desafios Essenciais
- Adicionar uma nova rota: Crie uma rota
/contactque retorne uma página HTML simples com informações de contato (um email fictício, por exemplo). - Lidar com diferentes métodos HTTP: Modifique a rota
/api/userspara que:GET /api/usersretorne a lista de usuários (como já faz).POST /api/users(apenas simule, não precisa persistir) retorne um JSON com uma mensagem "Usuário criado com sucesso!" e o método da requisição. (Dica: usereq.method === 'POST').
- Retornar HTML de um arquivo: Em vez de strings HTML longas, crie um arquivo
public/index.htmlepublic/about.htmle tente ler o conteúdo desses arquivos para enviá-los como resposta. (Dica: use o módulofsdo Node.js -fs.readFileSyncoufs.readFile). - Melhorar o tratamento de erros: Adicione um bloco
try...catchem sua lógica de roteamento para capturar erros inesperados e retornar um status500 Internal Server Errorcom uma mensagem amigável.
Desafios Extras (para os mais curiosos!)
- Modularizar as rotas: Para servidores maiores, a lógica
if/else ifpode ficar confusa. Tente criar um arquivoroutes.jsque exporte uma função ou um objeto que lide com o roteamento, e importe-o para seuindex.js. - Adicionar um pequeno middleware: Implemente uma função que logue a duração de cada requisição (tempo entre
reqeres.end()).
💡 8. Resumo e Próximos Passos
Nesta aula, você construiu um servidor HTTP funcional do zero, aprendendo sobre:
- Módulo
http: A base para criar servidores web no Node.js. requesteresponse: Objetos fundamentais para interagir com requisições e respostas.- Variáveis de Ambiente: Como usar
process.envedotenvpara configurações flexíveis e seguras. - Roteamento Básico: Direcionando requisições para diferentes URLs.
- Tipos de Conteúdo: Enviando HTML e JSON com
Content-Type. - Códigos de Status HTTP: Indicando o resultado da requisição (200 OK, 404 Not Found).
Este é um passo crucial para entender a arquitetura de aplicações web em Node.js. Embora o módulo http seja poderoso, para aplicações mais complexas, frameworks como o Express.js (que veremos nas próximas aulas!) simplificam enormemente o desenvolvimento, fornecendo uma estrutura mais robusta para roteamento, middlewares e tratamento de erros.
Próximos Passos:
- Explore os desafios propostos para aprofundar seu conhecimento.
- Comece a pesquisar sobre o Express.js e como ele abstrai muitos dos conceitos que você aprendeu aqui.
- Pense em como você poderia organizar um projeto Node.js maior para manter o código limpo e modular.
Parabéns por completar este projeto! Você está no caminho certo para se tornar um desenvolvedor Node.js competente! 🎉