HTML Diff
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 &lt;a href="/signup"&gt;Зарегистрироваться&lt;/a&gt;</li>
15 <li>В HTML &lt;a href="/signup"&gt;Зарегистрироваться&lt;/a&gt;</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>