1. Введение
Когда вы заходите на сайт с адресом вроде:
https://myapp.com/users/42
https://myapp.com/products/iphone-14
— вы, возможно, замечали, что цифра 42 или слово iphone-14 — это не просто случайные куски текста, а уникальные идентификаторы пользователя или товара. Такие "вставки" в URL называются параметрами маршрута (или route parameters, path parameters).
С помощью параметров маршрута мы можем создавать универсальные обработчики, которые будут реагировать на разные значения внутри URL. Например:
- /users/:id — получить пользователя по его id
- /posts/:postId/comments/:commentId — получить комментарий с определённым id к определённому посту
В Express.js такие параметры обозначаются двоеточием (:) перед именем параметра в строке маршрута. А сами значения потом попадают в объект req.params.
Объявление маршрута с параметрами
app.get('/users/:id', (req, res) => {
// ...
});
Здесь :id — это имя параметра маршрута. Express автоматически "вытащит" значение, которое стоит на этом месте в URL, и положит его в объект req.params под ключом id.
Пример
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`Вы запросили пользователя с id: ${userId}`);
});
Если теперь открыть в браузере или отправить GET-запрос на адрес /users/123, сервер ответит:
Вы запросили пользователя с id: 123
Важно:
Параметры маршрута — это всегда строки! Даже если в URL написано /users/42, значение req.params.id будет строкой "42".
2. Множественные параметры маршрута
Можно объявлять сразу несколько параметров в маршруте, просто добавляя новые :имя через слэш:
app.get('/posts/:postId/comments/:commentId', (req, res) => {
const postId = req.params.postId;
const commentId = req.params.commentId;
res.send(`Пост: ${postId}, комментарий: ${commentId}`);
});
Запрос к /posts/12/comments/5 вернёт:
Пост: 12, комментарий: 5
Как это работает внутри?
Express "разбирает" ваш маршрут, находит совпадения по шаблону и собирает значения в объект req.params:
// пример
console.log(req.params); // { postId: '12', commentId: '5' }
3. Применение параметров маршрута на практике
Давайте продолжим развивать наше простое Express-приложение, которое мы строили в прошлых лекциях.
Пример: API пользователей
Допустим, у нас есть массив пользователей (в реальной жизни тут была бы база данных, но пока обойдёмся массивом):
const users = [
{ id: '1', name: 'Иван' },
{ id: '2', name: 'Мария' },
{ id: '3', name: 'Джон' }
];
Теперь напишем маршрут, который по адресу /users/:id будет возвращать пользователя с нужным id:
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).send('Пользователь не найден');
}
res.json(user);
});
Объяснение:
- Мы берём значение параметра маршрута: const userId = req.params.id;
- Ищем пользователя с таким id в массиве.
- Если не нашли — возвращаем 404 (не найдено).
- Если нашли — возвращаем объект пользователя в формате JSON.
Пример запроса:
GET /users/2
Ответ:
{
"id": "2",
"name": "Мария"
}
Ещё пример: получение комментария к посту
Допустим, у нас есть структура:
const posts = [
{
id: '1',
title: 'Первый пост',
comments: [
{ id: 'a', text: 'Отличная статья!' },
{ id: 'b', text: 'Согласен с автором.' }
]
},
{
id: '2',
title: 'Второй пост',
comments: [
{ id: 'c', text: 'Спасибо за информацию!' }
]
}
];
Маршрут для получения конкретного комментария:
app.get('/posts/:postId/comments/:commentId', (req, res) => {
const { postId, commentId } = req.params;
const post = posts.find(p => p.id === postId);
if (!post) {
return res.status(404).send('Пост не найден');
}
const comment = post.comments.find(c => c.id === commentId);
if (!comment) {
return res.status(404).send('Комментарий не найден');
}
res.json(comment);
});
4. Особенности и нюансы работы с req.params
Все параметры — строки
Express не преобразует параметры в числа автоматически. Если вам нужно работать с числами, преобразуйте их явно:
const id = Number(req.params.id);
// или
const id = parseInt(req.params.id, 10);
Отсутствие параметра
Если в маршруте указан параметр, но в запросе его нет — такой маршрут просто не сработает. Например, маршрут /users/:id не сработает для запроса /users/ (без id).
Совмещение с query-параметрами
Параметры маршрута (req.params) — это то, что находится в пути (/users/:id).
Query-параметры (req.query) — это то, что после знака вопроса (?) в URL: /users/42?sort=desc.
Динамические маршруты и порядок их объявления
Express ищет подходящий маршрут сверху вниз. Если у вас есть похожие маршруты, порядок объявления имеет значение!
app.get('/users/new', ...); // 1
app.get('/users/:id', ...); // 2
Если поменять порядок, то запрос к /users/new попадёт в маршрут /users/:id с id = 'new'. Всегда объявляйте более конкретные маршруты выше!
Параметры с дефисами, подчеркиваниями, регулярками
Имя параметра может быть любым валидным идентификатором:
app.get('/users/:user_id', ...);
app.get('/users/:user-id', ...); // но тогда req.params['user-id']
Можно даже добавить регулярные выражения для параметра (продвинутый случай):
app.get('/users/:id(\\d+)', ...); // только если id — цифры
5. Как это выглядит в реальном приложении
Давайте соберём всё в одно мини-приложение:
const express = require('express');
const app = express();
const port = 3000;
const users = [
{ id: '1', name: 'Иван' },
{ id: '2', name: 'Мария' }
];
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).send('Пользователь не найден');
}
res.json(user);
});
app.listen(port, () => {
console.log(`Сервер запущен на http://localhost:${port}`);
});
6. Типичные ошибки при работе с req.params
Ошибка №1: Перепутали параметры маршрута и query-параметры.
req.params — это то, что в пути (/users/42), а req.query — это то, что после ? (/users?sort=desc). Если вы ищете id в req.query, а у вас маршрут /users/:id — ничего не найдёте!
Ошибка №2: Забыли преобразовать параметры в числа.
Все значения в req.params — строки. Если вы сравниваете с числом (user.id === req.params.id), а user.id — число, сравнение не сработает. Лучше приводить к одному типу.
Ошибка №3: Порядок маршрутов.
Если объявить общий маршрут /users/:id выше, чем /users/new, то запрос к /users/new попадёт в первый маршрут, а не во второй. Всегда объявляйте более конкретные маршруты выше общих.
Ошибка №4: Опечатки в имени параметра.
Если в маршруте написано /users/:userId, а вы обращаетесь к req.params.id — получите undefined. Имя должно совпадать!
Ошибка №5: Не обрабатываете случай, когда объект не найден.
Если пользователь с таким id не найден, всегда возвращайте 404, а не просто отправляйте пустой объект или ничего.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ