Criando um Servidor em Node.js
Para trabalhar com servidor e protocolo HTTP no Node.js, utilizamos o módulo http.
const http = require("http");
const server = http.createServer();
O método createServer()
retorna um objeto http.Server
. Para lidar com conexões, passamos uma função de callback para o método createServer
:
const http = require("http");
const server = http.createServer(function (request, response) {
response.setHeader("Content-Type", "text/html; charset=utf-8"); // serve para a correta exibição de caracteres especiais
response.end("Hello Proramício!");
});
Essa função aceita dois parâmetros:
request
: contém informações sobre a solicitaçãoresponse
: gerencia o envio da resposta
No exemplo acima, o método response.end()
envia a string "Hello Proramício!" como resposta para o cliente.
Para que o servidor possa escutar e processar conexões, devemos chamar o método listen()
no objeto do servidor. Este método pode aceitar diversos parâmetros, mas geralmente o primeiro parâmetro é o número da porta em que o servidor será iniciado:
const http = require("http");
const server = http.createServer(function (request, response) {
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.end("Hello Programício!");
});
server.listen(3000);
Nesse caso, o servidor será iniciado na porta 3000. Também podemos passar uma função para o método listen
, que será executada quando o servidor iniciar:
const http = require("http");
const server = http.createServer(function (request, response) {
response.end("Hello Programício");
});
server.listen(3000, function () {
console.log("Servidor iniciado no endereço http://localhost:3000");
});
Ao executar a aplicação, veremos a mensagem correspondente no console:
c:\app> node app.js Servidor iniciado no endereço http://localhost:3000
Como o servidor está rodando na porta 3000, podemos acessar nossa aplicação no navegador pelo endereço http://localhost:3000
.
Solicitação (Request)
O parâmetro request permite obter informações sobre a solicitação e representa um objeto http.IncomingMessage
. Algumas propriedades principais desse objeto são:
headers
: retorna os cabeçalhos da solicitaçãomethod
: tipo de solicitação (GET, POST, DELETE, PUT)url
: endereço solicitado
Por exemplo, considere o seguinte arquivo app.js
:
const http = require("http");
http
.createServer(function (request, response) {
console.log("Url:", request.url);
console.log("Tipo de solicitação:", request.method);
console.log("User-Agent:", request.headers["user-agent"]);
console.log("Todos os cabeçalhos:");
console.log(request.headers);
response.end();
})
.listen(3000, function () {
console.log("Servidor iniciado no endereço http://localhost:3000");
});
Ao executar e acessar http://localhost:3000
no navegador, veremos a informação da solicitação no console:
c:\app> Servidor iniciado no endereço http://localhost:3000 Url: / Tipo de solicitação: GET User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Todos os cabeçalhos: { host: 'localhost:3000', connection: 'keep-alive', 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"', 'sec-ch-ua-mobile': '?0', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36', 'sec-ch-ua-platform': '"Windows"', accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'no-cors', 'sec-fetch-dest': 'image', referer: 'http://localhost:3000/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,pt-BR;q=0.8,pt;q=0.7', }
Resposta (Response)
O parâmetro response
gerencia o envio da resposta e representa um objeto http.ServerResponse
. Entre suas funcionalidades, destacam-se os seguintes métodos:
statusCode
: define o código de status da respostastatusMessage
: define a mensagem enviada junto com o código de statussetHeader(name, value)
: adiciona um cabeçalho à respostawrite
: escreve conteúdo no fluxo de respostawriteHead
: adiciona um código de status e um conjunto de cabeçalhos à respostaend
: sinaliza ao servidor que os cabeçalhos e o corpo da resposta estão definidos, enviando a resposta ao cliente. Este método deve ser chamado em cada requisição.
Para enviar uma resposta, geralmente basta chamar o método end()
, passando os dados a serem enviados:
response.end("Hello Programício!");
Com o método write()
, podemos adicionar dados em partes à resposta. Por exemplo, altere o arquivo app.js
da seguinte forma:
const http = require("http");
http
.createServer(function (request, response) {
response.write("Texto 1\n");
response.write("Texto 2\n");
response.end("Fim");
})
.listen(3000, function () {
console.log("Servidor iniciado no endereço http://localhost:3000");
});
Executamos o arquivo e acessamos o programa no navegador:
Enviando Cabeçalhos
O método setHeader()
permite definir cabeçalhos para a resposta:
const http = require("http");
http
.createServer(function (_, response) {
response.setHeader("UserId", 12); // define um cabeçalho customizado
response.setHeader("Content-Type", "text/html; charset=utf-8;");
response.write(`
<h2>Olá, mundo</h2>
`);
response.end();
})
.listen(3000, function () {
console.log("Servidor iniciado no endereço http://localhost:3000");
});
Neste caso, para teste, definimos um cabeçalho customizado "UserId" com valor 12. E para que a resposta seja interpretada pelo navegador como código HTML, definimos o valor "text/html; charset=utf-8;" para o cabeçalho "Content-Type". O resultado é o seguinte:
Roteamento
Por padrão, o Node.js não possui um sistema de roteamento embutido. Normalmente, ele é implementado por frameworks especiais como Express, que será discutido no próximo capítulo. No entanto, se for necessário lidar com alguns poucos roteamentos simples, podemos utilizar a propriedade url
do objeto Request
. Por exemplo:
const http = require("http");
http
.createServer(function (request, response) {
response.setHeader("Content-Type", "text/html; charset=utf-8;");
if (request.url === "/home" || request.url === "/") {
response.write("Home");
} else if (request.url == "/about") {
response.write("About");
} else if (request.url == "/contact") {
response.write("Contacts");
} else {
response.write("Not found");
}
response.end();
})
.listen(3000);
Neste exemplo, são tratadas as rotas /home
, /about
e /contact
. Se o acesso for à raiz do site ou ao endereço localhost:3000/home
, será exibida a mensagem "Home". Se o acesso for ao endereço localhost:3000/about
, será exibida a mensagem "About", e assim por diante. Se o endereço solicitado não corresponder a nenhuma rota, será exibida a mensagem "Not Found".
No entanto, vale ressaltar que frameworks especiais como Express, que funcionam sobre o Node.js, oferecem maneiras mais convenientes de lidar com roteamento, sendo amplamente utilizados.
Redirecionamento
Redirecionamento envolve o envio de um código de status 301 (redirecionamento permanente) ou 302 (redirecionamento temporário) e um cabeçalho Location, que indica o novo endereço. Por exemplo, vamos redirecionar de localhost:3000/
para localhost:3000/newpage
:
const http = require("http");
http
.createServer(function (request, response) {
response.setHeader("Content-Type", "text/html; charset=utf-8;");
if (request.url === "/") {
response.statusCode = 302; // redirecionamento temporário
// para o endereço localhost:3000/newpage
response.setHeader("Location", "/newpage");
} else if (request.url == "/newpage") {
response.write("Novo endereço");
} else {
response.statusCode = 404; // endereço não encontrado
response.write("Não encontrado");
}
response.end();
})
.listen(3000);
Neste exemplo, ao acessar localhost:3000/
, o cliente será redirecionado para localhost:3000/newpage
. Se o acesso for ao endereço localhost:3000/newpage
, será exibida a mensagem "Novo endereço". Se o endereço solicitado não for encontrado, será exibida a mensagem "Não encontrado".