Добрый день, друзья! Сегодня мы разберемся, как работает роутинг в express.js. Для начала вспомним, что такое роутинг и для чего он служит.
Роутинг (его еще называют "маршрутизация" или "диспетчеризация") служит для того, чтобы определить, как приложение отвечает на HTTP-запросы.
За роутинг отвечает Роутер — специальный модуль, который понимает тип и адрес запроса.
Например, вы создаете магазин и хотите, чтобы по адресу www.my-super-store.com/products
открывалась страница
со всем товарами. Давайте попробуем сделать это в express.js.
/*
* 1) Создаем новое приложение
*/
const app = express()
/*
* 3) Добавляем роутинг для `/products`
*/
app.get('/products', (req, res) => {
/*
* 3.1) Добавляем обработчик запроса
* для примера мы будем просто отсылать демо-данные клиенту через res.json
*/
res.json(
[
{ id: 1, name: 'iphone 12', price: 600, slug: 'iphone_12'},
{ id: 1, name: 'iphone 12 mini', price: 500, slug: 'iphone_12_mini' },
{ id: 1, name: 'iphone SE 2020', count: 400, slug: 'iphone_SE_2020' },
]
)
})
/*
* Все, обработчик HTTP-запроса `GET /products` добавлен.
*/
/*
* 4) Запустим приложение
*/
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
После запуска приложение будет по запросу GET /products
отправлять нам наши тестовые данные.
Давайте проверим:
- В консоли
$ curl http://localhost:3000/products
- В браузере — введите в строку адреса
http://localhost:3000/products
Также можно и добавить обработчики для других типов запроса:
- app.post(...)
- app.put(...)
- app.patch(...)
- app.delete(...) и остальные HTTP-методы.
Общий вид такого добавления:
app.METHOD(path, callback [, callback ...])
А что делать с маршрутом, часть которого не известна на момент добавления? Типичный пример — карточка товара, которая открывается по названию или id.
Роутер позволяет сохранять части маршрута в переменные, указав в path
в какую переменную сохранить ту или иную часть. Переменная будет доступна
в req.params
. Например, если указать в path
строку '/products/:productId'
то productId
сохранится в req.params.productId
Смотрите:
app.get('/products/:productId', (req, res) => {
console.log(req.params.productId)
// запрос GET /products/123 выведет строку 123
})
Параметров может быть несколько:
app.get('/section/:sectionId/category/:categoryId', (req, res) => {
console.log(req.params)
// запрос GET /section/gadgets/category/smartphones выведет объект
// { sectionId: "gadgets", category: "smartphones" }
})
В path
можно указать регулярное выражение, path
может быть массивом.
Для параметров есть сокращенная запись app.param
.
Подробности — в документации
С ростом приложения и увеличением количества маршрутов становится удобным выносить роутинг в отдельные файлы.
Отдельный роутинг можно организивать через express.Router()
—
вызов этой функции возвратит отдельный роутер.
Пример использования:
index.js
const express = require('express')
const app = express()
/*
* Передаем `express` в модуль `router` чтобы внутри этого модуля вызвать `express.Router()`
*/
const router = require('./router')(express)
app.use(router)
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
router.js
const router = require('express').Router()
router.route('/cart/:id')
.get((req, res, next) => {})
.patch((req, res, next) => {})
.delete((req, res, next) => {})
module.exports = router
См. подробное описание в src/router
.