Seu primeiro middleware
Parte da seção Fundamentos de Express do Journey de Node.js da Coddy. Lição 13 de 23.
Algumas tarefas fazem parte de toda requisição, como escrever uma linha no log, e copiá-las para cada rota nunca teria fim. Toda requisição tem um método, em req.method: GET para buscar algo, POST para enviar algo.
let visits = 0;
app.use((req, res, next) => {
visits++;
next();
});Uma função passada para app.use é um middleware: o Express a executa para toda requisição, na ordem em que foi adicionado, antes das rotas abaixo dele. Ela recebe um terceiro argumento, next. Chamar next() passa a requisição adiante para o que vier a seguir. Um middleware que não responde nem chama next() deixa a requisição esperando para sempre.
express.static do capítulo anterior também é middleware: ele responde quando encontra um arquivo e chama next() quando não encontra.
Desafio
FácilVocê quer uma linha de registro para cada requisição recebida pelo servidor, para ver o que os visitantes solicitam.
- Em
server.js, logo apósconst app = express();, adicione um middleware comapp.use. Posicionado ali, ele é executado antes de cada rota. - Para cada requisição, ele imprime uma linha no Console: o método da requisição, um espaço e, em seguida, o caminho. Uma requisição para
/recipes/2imprimeGET /recipes/2. O método está emreq.method(GET,POSTe assim por diante), e o caminho está emreq.url. - Depois de imprimir, ele chama
next(), para que a requisição siga para as rotas.
Experimente: Pressione Executar e envie /recipes/2. Você deverá ver Pancakes, e o Console exibirá GET /recipes/2. Envie /api/recipes: a lista de sempre, e GET /api/recipes no Console. Envie /nope: uma resposta 404, e o Console ainda exibirá GET /nope, porque o middleware é executado antes de o Express procurar uma rota.
Experimente você mesmo
import { escapeHtml } from './html.js';
import express from 'express';
import { recipes } from './data.js';
const app = express();
app.use(express.static('public'));
app.get('/', (req, res) => {
const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});
// type('text') envia texto simples, então cada título aparece em sua própria linha.
app.get('/recipes', (req, res) => {
const { tag } = req.query;
const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});
app.get('/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).send('No such recipe');
return;
}
res.send(recipe.title);
});
app.get('/api/recipes', (req, res) => {
res.json(recipes);
});
app.get('/api/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).json({ error: 'No such recipe' });
return;
}
res.json(recipe);
});
app.get('/about', (req, res) => {
res.send('Recipe Box collects family recipes.');
});
app.get('/menu', (req, res) => {
res.redirect(301, '/recipes');
});
app.get('/menu/:id', (req, res) => {
res.redirect(301, `/recipes/${req.params.id}`);
});
app.listen(3000, () => {
console.log('Recipe Box is running on port 3000');
});
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Fundamentos de Express
Pratique por conta própria: Playground de Express