Rotas

Normalmente um web site tem várias páginas para apresentar ao utilizador. Saber que página apresentar a cada momento depende do url do pedido, ou seja, que página está a ser pedida nesse url.

As rotas são um mecanismo que analisa o url do pedido e decide que página apresentar.

Vamos ver um exemplo de um site com 3 páginas: login.html, admin.html e produtos.html.

Os url possíveis para este site são os seguintes:

http://localhost:8000/ vai para a página login.html
http://localhost:8000/admin vai para a página admin.html
http://localhost:8000/produtos vai para a página produtos.html

No ficheiro server.js vamos criar um servidor que vai escutar na porta 8000.

server.js:

var http = require("http");
var htmlserver = require("./modulos/htmlserver");

var server = http.createServer(function (req, res) {
  if (req.method == "GET") {
    const rota = req.url;

    switch (rota) {
      case "/":
        htmlserver.send("./pages/login.html", res);
        break;
      case "/admin":
        htmlserver.send("./pages/admin.html", res);
        break;
      case "/produtos":
        htmlserver.send("./pages/produtos.html", res);
        break;
      default:
        res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" });
        res.write("Página não encontrada");
        res.end();
    }
  }
});

server.listen(8000);

console.log("Servidor Node.js a correr na porta 8000 ..");

A aplicação usa 3 módulos:

  • O módulo http para criar o servidor.
  • O módulo htmlserver para enviar as páginas para o cliente

Na função anónima que passamos para o método createServer(), e que é chamada em cada pedido que o cliente faz ao servidor, começamos por verificar se o pedido é GET.

Se fôr um pedido GET, obtemos a rota do pedido a partir da propriedade url do objeto req:

const rota = req.url;

De seguida, analisamos a rota e numa instrução switch e, para cada opção chamamos o método sendr() do módulo htmlserver que envia a página respetiva para o cliente.

O módulo htmlserver é um módulo local que tem a função send() que, essencialmente, abre o ficheiro da página de html respetiva e envia os seus dados para o cliente:

Módulo htmlserver:

let fs = require("fs");

module.exports.send = function (path, response) {
  fs.readFile(path, "utf8", function (error, data) {
    if (error) {
      response.writeHead(404);
      response.write("file not found");
    } else {
      response.setHeader("content-type", "text/html; charset=utf-8");
      response.writeHead(200);
      response.write(data);
    }
    response.end();
  });
};

Rotas num módulo local

Normalmente, como um site pode ter muitas páginas, a codificação do código das rotas pode resultar em código extenso. Para não sobrecarregar a aplicação principal com esse código, podemos por a codificação das rotas num módulo à parte a que podemos chamar rotas.

Esse módulo terá uma função, rota(), que recebe o objeto response o o pathname da rota.

Essa função irá tratar todos as rotas, tal como fazia na aplicação principal:

rotas.js:

var html = require('./html'); 
 
module.exports.rota = function(res, path){ 
   switch (path) { 
      case '/': 
         html.render('./login.html', res); 
         break; 
      case '/admin': 
         html.render('./admin.html', res); 
         break; 
      case '/produtos': 
         html.render('./produtos.html', res); 
         break; 
      default: 
         res.writeHead(404, {"Content-Type": "text/html; charset=utf-8"}); 
         res.write('Página não encontrada'); 
         res.end(); 
   } 
} 

A aplicação principal (server.js) ficará muito mais simples como poderemos ver:

server.js:

var http = require('http'); 
var url = require('url'); 
var rotas = require('./rotas'); 
 
var server = http.createServer(function (req, res) { 
   if(req.method == "GET") { 
      let path = url.parse(req.url).pathname; 
      rotas.rota(res, path); 
   } 
}); 
 
server.listen(8000); 
 
console.log('Servidor Node.js a correr na porta 8000 ..')