Como Criar um Servidor Web com Express.js e Node.js
Criar um servidor web é uma habilidade fundamental para qualquer desenvolvedor web. Express.js, um framework minimalista para Node.js, é uma das ferramentas mais populares para esse propósito. Express simplifica a construção de servidores web e APIs, permitindo que você crie rapidamente aplicações robustas e escaláveis. Neste artigo, vamos explorar passo a passo como criar um servidor web com Express.js e Node.js, cobrindo desde a configuração inicial até a implementação de funcionalidades avançadas.
Pré-requisitos
Antes de começar, certifique-se de ter:
- Node.js instalado em sua máquina.
- Um editor de texto, como VSCode.
- Conhecimento básico de JavaScript e Node.js.
Configuração do Ambiente
1. Instalando Node.js
Se ainda não tiver o Node.js instalado, acesse o site oficial Node.js e baixe a versão apropriada para o seu sistema operacional. Siga as instruções de instalação fornecidas no site.
2. Inicializando o Projeto
Crie um novo diretório para o seu projeto e inicialize um projeto Node.js:
mkdir express-server
cd express-server
npm init -y
3. Instalando o Express.js
Instale o Express.js usando o npm:
npm install express
Criando o Servidor Básico
1. Estrutura do Projeto
Crie a seguinte estrutura de diretórios e arquivos:
express-server/
├── src/
│ └── index.js
├── package.json
└── .gitignore
2. Criando o Servidor
No arquivo src/index.js, adicione o seguinte código para criar um servidor básico com Express.js:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
Este código cria um servidor que escuta na porta 3000 e responde com “Hello, World!” quando a rota raiz (/) é acessada.
3. Executando o Servidor
Para executar o servidor, use o comando:
node src/index.js
Abra o navegador e acesse http://localhost:3000 para ver a mensagem “Hello, World!”.
Rotas e Controladores
1. Definindo Rotas
Rotas são URLs que sua aplicação pode responder. No Express, você pode definir rotas usando métodos como app.get(), app.post(), app.put(), app.delete(), etc. Vamos expandir nosso servidor para incluir mais rotas.
app.get('/about', (req, res) => {
res.send('About Us');
});
app.get('/contact', (req, res) => {
res.send('Contact Us');
});
2. Usando Controladores
Para manter o código organizado, vamos mover a lógica das rotas para controladores separados. Crie um diretório controllers dentro de src e adicione um arquivo mainController.js:
express-server/
├── src/
│ ├── controllers/
│ │ └── mainController.js
│ └── index.js
├── package.json
└── .gitignore
No arquivo mainController.js, adicione:
exports.home = (req, res) => {
res.send('Hello, World!');
};
exports.about = (req, res) => {
res.send('About Us');
};
exports.contact = (req, res) => {
res.send('Contact Us');
};
No index.js, modifique o código para usar os controladores:
const express = require('express');
const mainController = require('./controllers/mainController');
const app = express();
const port = 3000;
app.get('/', mainController.home);
app.get('/about', mainController.about);
app.get('/contact', mainController.contact);
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
Middleware
Middleware são funções que têm acesso ao objeto de solicitação (req), ao objeto de resposta (res) e à próxima função de middleware no ciclo de solicitação/resposta da aplicação. Vamos adicionar alguns middlewares úteis.
1. Middleware de Registro de Solicitações
Adicione um middleware para registrar todas as solicitações:
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
2. Middleware para Servir Arquivos Estáticos
Para servir arquivos estáticos como imagens, CSS e JavaScript, use o middleware express.static:
app.use(express.static('public'));
Crie um diretório public e adicione alguns arquivos estáticos para teste:
express-server/
├── public/
│ ├── css/
│ │ └── style.css
│ ├── images/
│ │ └── logo.png
│ └── js/
│ └── script.js
├── src/
│ ├── controllers/
│ │ └── mainController.js
│ └── index.js
├── package.json
└── .gitignore
Trabalhando com Dados
1. Recebendo Dados do Cliente
Para receber dados enviados pelo cliente, como em formulários, use o middleware express.json() e express.urlencoded():
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
2. Rota POST para Formulários
Vamos criar uma rota POST para lidar com dados de um formulário:
app.post('/submit', (req, res) => {
const { name, email } = req.body;
res.send(`Received submission: Name - ${name}, Email - ${email}`);
});
Crie um arquivo form.html no diretório public para testar a rota POST:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form Submission</title>
</head>
<body>
<form action="/submit" method="POST">
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<button type="submit">Submit</button>
</form>
</body>
</html>
Acesse http://localhost:3000/form.html no navegador para testar o formulário.
Integração com Banco de Dados
1. Instalando o Mongoose
Vamos usar o MongoDB como nosso banco de dados e o Mongoose como a biblioteca de modelagem de dados.
npm install mongoose
2. Configurando o Mongoose
Adicione a configuração do Mongoose no index.js:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/expressdb', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'Erro de conexão:'));
db.once('open', () => {
console.log('Conectado ao MongoDB');
});
3. Criando um Modelo
Crie um modelo de usuário no diretório models:
express-server/
├── public/
│ ├── css/
│ │ └── style.css
│ ├── images/
│ │ └── logo.png
│ └── js/
│ └── script.js
├── src/
│ ├── controllers/
│ │ └── mainController.js
│ ├── models/
│ │ └── user.js
│ └── index.js
├── package.json
└── .gitignore
No arquivo user.js, adicione o seguinte código:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String
});
const User = mongoose.model('User', userSchema);
module.exports = User;
4. Salvando Dados no Banco de Dados
Modifique o controlador para salvar dados no banco de dados:
const User = require('../models/user');
exports.submitForm = async (req, res) => {
const { name, email } = req.body;
const user = new User({ name, email });
try {
await user.save();
res.send(`User ${name} saved successfully.`);
} catch (err) {
res.status(500).send('Error saving user.');
}
};
E modifique o index.js para usar a nova rota POST:
const express = require('express');
const mainController = require('./controllers/mainController');
const mongoose = require('mongoose');
const app = express();
const port = 3000;
mongoose.connect('mongodb://localhost:27017/expressdb', {
useNewUrlParser: true,
useUnifiedTopology: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console
, 'Erro de conexão:'));
db.once('open', () => {
console.log('Conectado ao MongoDB');
});
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', mainController.home);
app.get('/about', mainController.about);
app.get('/contact', mainController.contact);
app.post('/submit', mainController.submitForm);
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
Implementando Autenticação
1. Instalando Bibliotecas de Autenticação
Vamos usar o bcrypt para hashing de senhas e jsonwebtoken para tokens JWT.
npm install bcrypt jsonwebtoken
2. Registrando Usuários
Crie um novo controlador para registro de usuários:
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const User = require('../models/user');
exports.register = async (req, res) => {
const { name, email, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
const user = new User({ name, email, password: hashedPassword });
try {
await user.save();
res.send(`User ${name} registered successfully.`);
} catch (err) {
res.status(500).send('Error registering user.');
}
};
Atualize o user.js para incluir o campo de senha:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String,
password: String
});
const User = mongoose.model('User', userSchema);
module.exports = User;
Adicione a nova rota de registro no index.js:
app.post('/register', mainController.register);
3. Autenticando Usuários
Adicione um controlador para autenticação:
exports.login = async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(400).send('Invalid email or password.');
}
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) {
return res.status(400).send('Invalid email or password.');
}
const token = jwt.sign({ _id: user._id }, 'secretKey');
res.header('auth-token', token).send(token);
};
Adicione a nova rota de login no index.js:
app.post('/login', mainController.login);
4. Protegendo Rotas
Crie um middleware para verificar o token JWT:
const jwt = require('jsonwebtoken');
function auth(req, res, next) {
const token = req.header('auth-token');
if (!token) return res.status(401).send('Access denied.');
try {
const verified = jwt.verify(token, 'secretKey');
req.user = verified;
next();
} catch (err) {
res.status(400).send('Invalid token.');
}
}
module.exports = auth;
Use o middleware em rotas protegidas:
const auth = require('./middleware/auth');
app.get('/private', auth, (req, res) => {
res.send('This is a private route.');
});
Conclusão
Criar um servidor web com Express.js e Node.js é um processo que envolve várias etapas, desde a configuração inicial até a implementação de funcionalidades avançadas como autenticação e integração com banco de dados. Com este guia, você aprendeu a criar um servidor básico, definir rotas e controladores, usar middleware, trabalhar com dados e implementar autenticação. Agora você está pronto para construir aplicações web robustas e escaláveis com Express.js e Node.js.
