0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Любое приложение на Express состоит минимум из трёх элементов:</p>
1
<p>Любое приложение на Express состоит минимум из трёх элементов:</p>
2
<ol><li>Создание объекта приложения;</li>
2
<ol><li>Создание объекта приложения;</li>
3
<li>Определение обработчиков маршрутов;</li>
3
<li>Определение обработчиков маршрутов;</li>
4
<li>Запуск приложения на определённом порту.</li>
4
<li>Запуск приложения на определённом порту.</li>
5
</ol><p>С первым и последним пунктом всё более-менее понятно, а вот обработчики - это уже интересно. Напомню, что микрофреймворки строятся по схеме: http verb + path + callback. В случае Express глагол определяется функцией, которая вызывается на объекте app. Например если мы хотим определить маршрут GET /, то для этого необходимо вызывать функцию get и первым параметром передать в неё строку /. Таким же образом нужно поступать для любого другого маршрута. Вот список глаголов, которые нас будут интересовать в процессе этого курса:</p>
5
</ol><p>С первым и последним пунктом всё более-менее понятно, а вот обработчики - это уже интересно. Напомню, что микрофреймворки строятся по схеме: http verb + path + callback. В случае Express глагол определяется функцией, которая вызывается на объекте app. Например если мы хотим определить маршрут GET /, то для этого необходимо вызывать функцию get и первым параметром передать в неё строку /. Таким же образом нужно поступать для любого другого маршрута. Вот список глаголов, которые нас будут интересовать в процессе этого курса:</p>
6
<p>Семантика http подразумевает, что глаголы<em>get</em>,<em>delete</em>,<em>head</em>и<em>put</em>, являются идемпотентными. Это должно обеспечиваться программистом, который реализует обработчики.</p>
6
<p>Семантика http подразумевает, что глаголы<em>get</em>,<em>delete</em>,<em>head</em>и<em>put</em>, являются идемпотентными. Это должно обеспечиваться программистом, который реализует обработчики.</p>
7
<h2>Динамические маршруты</h2>
7
<h2>Динамические маршруты</h2>
8
<p>Самая главная и мощная функциональность системы роутинга - это работа с динамическими маршрутами.</p>
8
<p>Самая главная и мощная функциональность системы роутинга - это работа с динамическими маршрутами.</p>
9
<p>Для динамических частей используется заполнитель :name, который состоит из двоеточия и произвольного имени. Express производит сопоставление актуального запроса со всеми шаблонами в порядке определения и выполняет соответствующие обработчики. Все динамические части маршрута попадают в объект req.params.</p>
9
<p>Для динамических частей используется заполнитель :name, который состоит из двоеточия и произвольного имени. Express производит сопоставление актуального запроса со всеми шаблонами в порядке определения и выполняет соответствующие обработчики. Все динамические части маршрута попадают в объект req.params.</p>
10
<p>Кроме этого, Express позволяет использовать регулярные выражения прямо в шаблоне:</p>
10
<p>Кроме этого, Express позволяет использовать регулярные выражения прямо в шаблоне:</p>
11
<p>Честно говоря, за свой многолетний опыт я не припомню ситуацию, когда мне это могло понадобиться. Всегда, если у вас есть возможность управлять урлами, можно сделать хороший вариант на одних плейсхолдерах (заполнителях), без прямого использования регулярных выражений.</p>
11
<p>Честно говоря, за свой многолетний опыт я не припомню ситуацию, когда мне это могло понадобиться. Всегда, если у вас есть возможность управлять урлами, можно сделать хороший вариант на одних плейсхолдерах (заполнителях), без прямого использования регулярных выражений.</p>
12
<h2>Именованные маршруты</h2>
12
<h2>Именованные маршруты</h2>
13
<p>В приложении есть различные роуты. Например, у авторизации может стоять роут /signup. Когда мы отдаем с сервера HTML, то этот адрес мы прописываем дважды:</p>
13
<p>В приложении есть различные роуты. Например, у авторизации может стоять роут /signup. Когда мы отдаем с сервера HTML, то этот адрес мы прописываем дважды:</p>
14
<ul><li>В роуте на сервере app.post('/signup', signupHandler)</li>
14
<ul><li>В роуте на сервере app.post('/signup', signupHandler)</li>
15
<li>В HTML <a href="/signup">Зарегистрироваться</a></li>
15
<li>В HTML <a href="/signup">Зарегистрироваться</a></li>
16
</ul><p>Про такое решение обычно говорят "хардкодить ссылки" или "магические строки". Если по какой-то причине мы решим переименовать этот роут, например, в /register, то нам надо поменять его и в роутах, и в HTML. В реальных приложениях роутов много, они состоят из нескольких частей, и переименование - не такая уж редкость.</p>
16
</ul><p>Про такое решение обычно говорят "хардкодить ссылки" или "магические строки". Если по какой-то причине мы решим переименовать этот роут, например, в /register, то нам надо поменять его и в роутах, и в HTML. В реальных приложениях роутов много, они состоят из нескольких частей, и переименование - не такая уж редкость.</p>
17
<p>Чтобы облегчить работу с именованием роутов, можно выделить их в отдельную константу и переиспользовать ее:</p>
17
<p>Чтобы облегчить работу с именованием роутов, можно выделить их в отдельную константу и переиспользовать ее:</p>
18
<p>Так мы сделаем именованные роуты. Теперь все адреса записаны в одном месте и их легко поменять. Весь остальной код будет использовать эти имена.</p>
18
<p>Так мы сделаем именованные роуты. Теперь все адреса записаны в одном месте и их легко поменять. Весь остальной код будет использовать эти имена.</p>
19
<p>Есть другой подход в создании именованных роутеров - с помощью специальных библиотек. Например, named-routes:</p>
19
<p>Есть другой подход в создании именованных роутеров - с помощью специальных библиотек. Например, named-routes:</p>
20
<p>В примере выше был создан именованный маршрут admin.user. Теперь, где-то в другом обработчике можно строить ссылки используя имя маршрута:</p>
20
<p>В примере выше был создан именованный маршрут admin.user. Теперь, где-то в другом обработчике можно строить ссылки используя имя маршрута:</p>
21
<p>Преимущества:</p>
21
<p>Преимущества:</p>
22
<ul><li>Если удалится маршрут, то при генерации ссылки мы получим исключение, и тесты его поймают</li>
22
<ul><li>Если удалится маршрут, то при генерации ссылки мы получим исключение, и тесты его поймают</li>
23
<li>Если изменится маршрут, то везде будут автоматически подставлены новые адреса</li>
23
<li>Если изменится маршрут, то везде будут автоматически подставлены новые адреса</li>
24
</ul><p>Чтобы сделать именованный роутинг действительно полезным и удобным, в других языках фреймворки предоставляют готовые решения, но в Express из коробки такой возможности нет. Поэтому в упражнениях мы продолжим хардкодить ссылки, но попробовать именованный роутинг можно будет в проекте.</p>
24
</ul><p>Чтобы сделать именованный роутинг действительно полезным и удобным, в других языках фреймворки предоставляют готовые решения, но в Express из коробки такой возможности нет. Поэтому в упражнениях мы продолжим хардкодить ссылки, но попробовать именованный роутинг можно будет в проекте.</p>
25
<h2>Request/Response</h2>
25
<h2>Request/Response</h2>
26
<p>Каждый определяемый обработчик принимает на вход два параметра: req и res. В этом смысле, всё очень похоже на ситуацию с http модулем с той лишь разницей, что там подобный обработчик один, а здесь на каждый маршрут свой. Request и Response предоставляют упрощенный интерфейс. Больше нет необходимости, по крайней мере в простых случаях, пользоваться ими как eventEmitter. На каждую задачу эти объекты предоставляют метод или свойство.</p>
26
<p>Каждый определяемый обработчик принимает на вход два параметра: req и res. В этом смысле, всё очень похоже на ситуацию с http модулем с той лишь разницей, что там подобный обработчик один, а здесь на каждый маршрут свой. Request и Response предоставляют упрощенный интерфейс. Больше нет необходимости, по крайней мере в простых случаях, пользоваться ими как eventEmitter. На каждую задачу эти объекты предоставляют метод или свойство.</p>
27
<p>Пройдёмся по базовым возможностям:</p>
27
<p>Пройдёмся по базовым возможностям:</p>
28
<ul><li>req.query готовый к обработке query string, другими словами вам не придётся парсить эти параметры, они уже поступают в виде объекта;</li>
28
<ul><li>req.query готовый к обработке query string, другими словами вам не придётся парсить эти параметры, они уже поступают в виде объекта;</li>
29
<li>Установка статуса работает через метод res.status(code);</li>
29
<li>Установка статуса работает через метод res.status(code);</li>
30
<li>Отправка данных выполняется функцией res.send(data). Все необходимые заголовки выставляются автоматически;</li>
30
<li>Отправка данных выполняется функцией res.send(data). Все необходимые заголовки выставляются автоматически;</li>
31
<li>Если необходимо отдавать данные в виде json, то Express позволяет это делать без использования дополнительных механизмов. Всё что нужно сделать это вызвать метод res.json(data), и данные будут автоматически сериализованы и отправлены клиенту.</li>
31
<li>Если необходимо отдавать данные в виде json, то Express позволяет это делать без использования дополнительных механизмов. Всё что нужно сделать это вызвать метод res.json(data), и данные будут автоматически сериализованы и отправлены клиенту.</li>
32
</ul>
32
</ul>