Traduzir esta página

Roteamento

Routing refere-se a como os endpoints de um aplicativo (URIs) respondem às solicitações do cliente. Para uma introdução ao roteamento, veja Roteamento básico.

Você define roteamento usando métodos do objeto Express app que correspondem aos métodos HTTP; por exemplo, app. et() para lidar com solicitações GET e app.post para lidar com solicitações POST. Para obter uma lista completa, ver app.METHOD. Você também pode usar o app.all() para lidar com todos os métodos HTTP e app. se() para especifique middleware como função de retorno de chamada (Veja Usando middleware para detalhes).

Esses métodos de roteamento especificam uma função de callback (às vezes chamada de “funções de manipulador”) chamada quando a aplicação recebe uma solicitação para a rota especificada (endpoint) e método HTTP. Em outras palavras, o aplicativo “listas” para solicitações que correspondem com a(s) rota(s) e método(s) especificado(s), e quando ela detecta uma correspondência, ela chama a função de retorno de chamada especificado.

Na verdade, os métodos de roteamento podem ter mais de uma função de callback como argumentos. Com múltiplas funções de callback, é importante fornecer next como um argumento para a função de callback e então chamar next() dentro do corpo da função para liberar o controle para a próxima callback.

O código a seguir é um exemplo de uma rota muito básica.

const express = require('express');
const app = express();
// respond with "hello world" when a GET request is made to the homepage
app.get('/', (req, res) => {
res.send('hello world');
});

Métodos de rota

Um método de route é derivado de um dos métodos HTTP e é anexado a uma instância da classe ‘express’.

O código a seguir é um exemplo de rotas que são definidas para os métodos GET e POST para a raiz do aplicativo.

// GET method route
app.get('/', (req, res) => {
res.send('GET request to the homepage');
});
// POST method route
app.post('/', (req, res) => {
res.send('POST request to the homepage');
});

Expresso suporta métodos que correspondem a todos os métodos de requisição HTTP: get, post, e assim por diante. Para uma lista completa, consulte app.METHOD.

Há um método de roteamento especial, app.all(), usado para carregar funções de middleware em um caminho para os métodos de requisição HTTP. Por exemplo, o seguinte manipulador é executado para solicitações para a rota "/secre" usando GET, POST, PUT, DELETE, ou qualquer outro método de solicitação HTTP suportado no módulo http.

app.all('/secret', (req, res, next) => {
console.log('Accessing the secret section ...');
next(); // pass control to the next handler
});

Caminho da rota

Roteamento, em combinação com um método de solicitação, defina os pontos de extremidade em que as solicitações podem ser feitas. Caminhos de rota podem ser strings ou expressões regulares.

Expresso usa path-to-regexp v8 para combinar com os caminhos da rota; veja a documentação pai-para-regexp para todas as possibilidades de definir caminhos da rota. Express Playground Router é uma ferramenta útil para testar rotas Express, embora não suporte correspondência de padrões.

Caminhos do texto

Os caminhos de strings correspondem exatamente às requisições. O ponto (.) e o hífen (-) são interpretados literalmente.

Warning

strings de consulta não fazem parte do caminho de rota.
app.get('/', (req, res) => {
res.send('root');
});
app.get('/about', (req, res) => {
res.send('about');
});
app.get('/random.text', (req, res) => {
res.send('random.text');
});

Caracteres curinga

Caracteres curinga correspondem a qualquer caminho após um prefixo. Eles devem ter um nome, assim como os parâmetros de rota, e são capturados como matrizes dos segmentos de caminho.

app.get('/files/*filepath', (req, res) => {
// GET /files/images/logo.png
console.dir(req.params.filepath);
// => [ 'images', 'logo.png' ]
res.send(`File: ${req.params.filepath.join('/')}`);
});

Para também coincidir com o caminho raiz, envolva o caractere curinga nos chaves:

// Matches / , /foo , /foo/bar , etc.
app.get('/{*splat}', (req, res) => {
// GET / => req.params.splat = []
// GET /foo/bar => req.params.splat = [ 'foo', 'bar' ]
res.send('ok');
});

Segmentos opcionais

Use chaves para definir segmentos opcionais em um caminho de rota. Quando o segmento não está presente, o parâmetro é omitido de req.params.

app.get('/:file{.:ext}', (req, res) => {
// GET /image.png => req.params = { file: 'image', ext: 'png' }
// GET /image => req.params = { file: 'image' }
res.send('ok');
});

Os caracteres ?, +, *, [], and () são reservados e não podem ser usados como caracteres literais nos caminhos da rota. Use \ para escapar deles se necessário.

Expressões regulares

Você também pode usar expressões regulares como caminhos de rota. Isto é útil quando você precisa de uma lógica de correspondência mais complexa.

// Matches any path containing "a"
app.get(/a/, (req, res) => {
res.send('/a/');
});
// Matches paths ending with "fly" (butterfly, dragonfly, etc.)
app.get(/.*fly$/, (req, res) => {
res.send('/.*fly$/');
});

Parâmetros de rota

Parâmetros de rota são denominados segmentos de URL que são usados para capturar os valores especificados em sua posição na URL. Os valores capturados são preenchidos no objeto req.params, com o nome do parâmetro de rota especificado no caminho como suas respectivas chaves.

Route path: /users/:userId/books/:bookId
Request URL: http://localhost:3000/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }

Para definir rotas com parâmetros de rota, simplesmente especifique os parâmetros de rota no caminho da rota, conforme mostrado abaixo.

app.get('/users/:userId/books/:bookId', (req, res) => {
res.send(req.params);
});

O nome dos parâmetros de rota deve ser composto de “palavra caracteres” ([A-Za-z0-9_]).

Como o hífen (-) e o ponto (.) são interpretados literalmente, eles podem ser usados juntamente com parâmetros de rota para fins úteis.

Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }

Caracteres Regexp não são suportados nos caminhos da rota. Use uma matriz de caminhos ou expressões regulares em vez disso. Veja a sintaxe correspondente à trajetória para obter mais informações.

Manipuladores de rota

Você pode fornecer várias funções de retorno de chamada que se comportam como middleware para lidar com uma solicitação. A única exceção é que esses callbacks podem invocar next('route') para ignorar as chamadas restantes da rota. Você pode usar este mecanismo para impor pré-condições em uma rota, então passe controle para rotas subsequentes se não houver motivo para prosseguir com a rota atual.

app.get('/user/:id', (req, res, next) => {
if (req.params.id === '0') {
return next('route');
}
res.send(`User ${req.params.id}`);
});
app.get('/user/:id', (req, res) => {
res.send('Special handler for user ID 0');
});

Neste exemplo:

  • GET /user/5 → tratado pela primeira rota → envia “Usuário 5”
  • GET /user/0 → primeira rota chama next('rote'), pulando para a próxima rota /user/:id correspondente

Os manipuladores de rotas podem estar na forma de uma função, um array de funções ou combinações de ambos, como mostrado nos exemplos a seguir.

Uma única função de retorno de chamada pode manipular uma rota. Por exemplo:

app.get('/example/a', (req, res) => {
res.send('Hello from A!');
});

Mais de uma função de retorno de chamada pode manipular uma rota (certifique-se de especificar o objeto next). Por exemplo:

app.get(
'/example/b',
(req, res, next) => {
console.log('the response will be sent by the next function ...');
next();
},
(req, res) => {
res.send('Hello from B!');
}
);

Um array de funções de retorno de chamada pode lidar com uma rota. Por exemplo:

const cb0 = function (req, res, next) {
console.log('CB0');
next();
};
const cb1 = function (req, res, next) {
console.log('CB1');
next();
};
const cb2 = function (req, res) {
res.send('Hello from C!');
};
app.get('/example/c', [cb0, cb1, cb2]);

Uma combinação de funções independentes e matrizes de funções pode lidar com uma rota. Por exemplo:

const cb0 = function (req, res, next) {
console.log('CB0');
next();
};
const cb1 = function (req, res, next) {
console.log('CB1');
next();
};
app.get(
'/example/d',
[cb0, cb1],
(req, res, next) => {
console.log('the response will be sent by the next function ...');
next();
},
(req, res) => {
res.send('Hello from D!');
}
);

Métodos de resposta

Os métodos no objeto de resposta (‘res’) na tabela a seguir podem enviar uma resposta para o cliente e encerrar o ciclo de resposta de solicitação. Se nenhum destes métodos for chamado de um manipulador de redes, a solicitação do cliente será deixada em suspenso.

MétodoDescrição:
res.download()Solicite que um arquivo seja baixado.
res.end()Encerrar o processo de resposta.
res.json()Enviar uma resposta JSON.
res.jsonp()Envie uma resposta JSON com suporte a JSONP.
res.redirect()Redirecionar uma requisição.
res.render()Renderizar um modelo de visão.
res.send()Envie uma resposta de vários tipos.
res.sendFile()Envia um arquivo como uma transmissão octet.
res.sendStatus()Defina o código de status da resposta e envie sua representação de string como o corpo da resposta.

app.route()

Você pode criar manipuladores de rotas em cadeia para um caminho de rota usando app.route(). Como o caminho é especificado em um único local, é útil criar rotas modulares, assim como reduzir a redundância e os tipos. Para obter mais informações sobre rotas, consulte: documentação de roteador.

Aqui está um exemplo de manipuladores de rota encadeados que são definidos usando app.route().

app
.route('/book')
.get((req, res) => {
res.send('Get a random book');
})
.post((req, res) => {
res.send('Add a book');
})
.put((req, res) => {
res.send('Update the book');
});

expressão.Roteador

Use a classe ‘express.Router’ para criar módulo, manipuladores de rotas montáveis. Uma instância Router é um sistema completo de middleware e roteamento; por este motivo, é muitas vezes referido como um “mini-app”.

O exemplo a seguir cria um roteador como um módulo, carrega uma função middleware nele define algumas rotas e monta o módulo do roteador em um caminho no aplicativo principal.

Crie um arquivo de roteador chamado birds.js no diretório de aplicativos, com o seguinte conteúdo:

const express = require('express');
const router = express.Router();
// middleware that is specific to this router
const timeLog = (req, res, next) => {
console.log('Time: ', Date.now());
next();
};
router.use(timeLog);
// define the home page route
router.get('/', (req, res) => {
res.send('Birds home page');
});
// define the about route
router.get('/about', (req, res) => {
res.send('About birds');
});
module.exports = router;

Em seguida, carregue o módulo do roteador no aplicativo:

const birds = require('./birds');
// ...
app.use('/birds', birds);

O aplicativo agora poderá lidar com pedidos para /birds e /birds/about, Além de chamar a função middleware timeLog que é específica da rota.

Mas se a rota pai /birds tiver parâmetros de caminho, ela não será acessível por padrão nas sub-rotas. Para torná-lo acessível, você precisará passar a opção mergeParams para o construtor do roteador reference.

const router = express.Router({ mergeParams: true });