mecanismo de roteamento do Express utiliza muito bem esse recurso, permitindo
a criação de callback encadeados em uma rota. Resumindo, quando criamos uma
rota, após informar no primeiro parâmetro a sua string, no segundo parâmetro em
diante é possível incluir callbacks que são executados de forma ordenada, por exem-
plo: app.get('/', callback1, callback2, callback3).
Para implementarmos isso, primeiro vamos criar o filtro de autenticação. Ele
será a criação do nosso primeiro middleware e será utilizado na maioria das rotas.
Na raiz do projeto crie a pasta middleware incluindo o arquivo autenticador.js,
nele implemente a lógica abaixo:
module.exports = function(req, res, next) {
if(!req.session.usuario) {
return res.redirect('/');
}
return next();
};
Esse filtro faz uma simples verificação se existe um usuário dentro da ses-
são. Se o usuário estiver autenticado, ou seja, estiver na session, será execu-
tado o callback return next() responsável por pular este filtro e indo para fun-
ção ao lado. Caso autenticação não aconteça, executamos um simples return
55
5.5. Indo além: criando páginas de erros amigáveis
Casa do Código
res.redirect('/'), que faz o usuário voltar para página inicial e impedindo
que ocorra o bug.
Com esse filtro implementado,
agora temos que injetá-lo nos call-
backs das rotas que precisam desse tratamento, faremos essas alterações no
routes/contatos.js, de acordo com o código a seguir:
module.exports = function(app) {
var autenticar = require('./../middleware/autenticador')
, contatos = app.controllers.contatos;
app.get('/contatos', autenticar, contatos.index);
app.get('/contato/:id', autenticar, contatos.show);
app.post('/contato', autenticar, contatos.create);
app.get('/contato/:id/editar', autenticar, contatos.edit);
app.put('/contato/:id', autenticar, contatos.update);
app.del('/contato/:id', autenticar, contatos.destroy);
};
Basicamente inserimos o callback autenticar antes da função principal da
rota. Isso nos permitiu emular a execução de um filtro before. Caso queira criar
um filtro after, não há segredos: apenas coloque o callback do filtro por último.
O importante é colocar as funções na ordem lógica de suas execuções.
5.5
Indo além: criando páginas de erros amigáveis
O Express oferece suporte para roteamento e renderização de erros do protocolo
HTTP. Ele possui apenas duas funções, uma específica para tratamento do famoso
erro 404 (página não encontrada) e uma função genérica que recebe por parâmetro uma variável contendo detalhes sobre o status e mensagem do erro HTTP.
Sobre o código de erros do HTTP
O protocolo HTTP tem diversos tipos de erros. O órgão W3C pos-
sui uma documentação explicando em detalhes o comportamento e có-
digo de cada erro. Para ficar por dentro desse assunto veja nesse link
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) a especifica-
ção dos status de erro gerados por este protocolo.
56
Casa do Código
Capítulo 5. Dominando o Express
Que tal implementarmos um controle de erros para renderizar aos usuários pá-
ginas customizadas e mais amigáveis? Primeiro, crie duas novas views, uma para
apresentar a tela do erro 404 conhecida na web como "Página não encontrada , seu nome será not-found.ejs...
<% include header %>
<header>
<h1>Ntalk</h1>
<h4>Infelizmente essa página não existe :(</h4>
</header>
<hr>
<p>Vamos voltar <a href="/">home page?</a> :)</p>
<% include footer %>
...e a outra será focada em mostrar erros gerados pelo protocolo HTTP com o
nome de server-error.ejs:
<% include header %>
<header>
<h1>Ntalk</h1>
<h4>Aconteceu algo terrível! :(</h4>
</header>
<p>
Veja os detalhes do erro:
<br>
<%- error.message %>
</p>
<hr>
<p>Que tal voltar <a href="/">home page?</a> :)</p>
<% include footer %>
Feito isso, agora só precisamos adicionar dois novos itens na stack de configura-
ções do app.js para renderizar as respectivas views de erros:
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.cookieParser('ntalk'));
app.use(express.session());
app.use(express.json());
app.use(express.urlencoded());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
57
5.5. Indo além: criando páginas de erros amigáveis
Casa do Código
app.use(function(req, res, next) {
res.status(404);
res.render('not-found');
});
app.use(function(error, req, res, next) {
res.status(500);
res.render('server-error', error);
});
Para minimizar essa poluição de código na stack do servidor, exporte as funções
de erros para um novo arquivo chamado error.js dentro do diretório middleware,
deixando-as da seguinte forma:
exports.notFound = function(req, res, next) {
res.status(404);
res.render('not-found');
};
exports.serverError = function(error, req, res, next) {
res.status(500);
res.render('server-error', {error: error});
};
Em seguida modifique o stack do app.js para ficar mais limpo:
var express = require('express')
, app = express()