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. For a full list, see app.METHOD. You can also use app.all() to handle all HTTP methods and app.use() to specify middleware as the callback function (See Using middleware for details).

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. 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.

index.cjs
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. For a full list, see 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. For example, the following handler is executed for requests to the route "/secret" whether using GET, QUERY, POST, PUT, DELETE, or any other HTTP request method supported in the http module.

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. They can also capture values from the URL, as described in Route parameters below.

Note

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');
});

Caution

The characters ?, +, *, [], (), and ! are reserved and cannot be used as literal characters in route paths, and braces are reserved for optional segments. 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. They come in three forms: named parameters (:name), wildcards (*name), and optional segments, which wrap either of them in braces.

Named parameters

Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below.

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);
});

In TypeScript, @types/express infers the parameters from the route path, so in the handler above req.params.userId and req.params.bookId are already typed as string with no extra annotation. Reading a name that is not in the route (such as req.params.other) is a type error. You only need to annotate the parameters when the handler is defined separately from the route, because the type checker can no longer see the path. In that case, pass them as the first type argument of Request:

import { type Request, type Response } from 'express';
const sendParams = (req: Request<{ userId: string; bookId: string }>, res: Response) => {
res.send(req.params);
};
app.get('/users/:userId/books/:bookId', sendParams);

Caution

The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example :"user-name".

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" }

Caution

Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as :userId(\d+). Use an array of paths or a full regular expression instead. Veja a sintaxe correspondente à trajetória para obter mais informações.

Wildcards

Caracteres curinga correspondem a qualquer caminho após um prefixo. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string.

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 is omitted
// 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');
});

The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters:

app.get('/user/{:id}', (req, res) => {
// GET /user/42 => req.params = { id: '42' }
// GET /user/ => req.params = {}
// GET /user => 404, only the parameter is optional
res.send('ok');
});
app.get('/order{/:id}', (req, res) => {
// GET /order/42 => req.params = { id: '42' }
// GET /order => req.params = {}, the whole segment is optional
res.send('ok');
});

Não confunda a posição da barra no caminho da rota com a configuração strict routing, que diz respeito à URL da requisição: ela controla se uma URL terminada em barra que o caminho da rota não exige ainda corresponde. Por exemplo, uma requisição para /order/ corresponde à rota /order{/:id} por padrão, mas retorna um erro 404 quando o strict routing está habilitado; a barra final de /user/ não é afetada porque a rota /user/{:id} a exige. Todas as requisições comentadas nos exemplos acima se comportam da mesma forma independentemente dessa configuração.

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('route'), 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

The methods on the response object (res) in the following table can send a response to the client, and terminate the request-response cycle. 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(). Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the Router() documentation.

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.Router

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:

birds.cjs
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:

index.cjs
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. To make it accessible, you will need to pass the mergeParams option to the Router constructor.

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