HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>В веб-разработке, процесс, который отвечает за определение обработчика для конкретной запрашиваемой страницы, называется маршрутизация. Чаще говорят "роутинг". Посмотрим на пример:</p>
1 <p>В веб-разработке, процесс, который отвечает за определение обработчика для конкретной запрашиваемой страницы, называется маршрутизация. Чаще говорят "роутинг". Посмотрим на пример:</p>
2 <p>https://ru.hexlet.io/code_reviews/4172 https://ru.hexlet.io/courses/programming-basics https://ru.hexlet.io/account/profile/edit</p>
2 <p>https://ru.hexlet.io/code_reviews/4172 https://ru.hexlet.io/courses/programming-basics https://ru.hexlet.io/account/profile/edit</p>
3 <p>Каждый адрес из примера выше представляет собой конкретный маршрут (роут). Причём их можно разделить по типу: статические и динамические.</p>
3 <p>Каждый адрес из примера выше представляет собой конкретный маршрут (роут). Причём их можно разделить по типу: статические и динамические.</p>
4 <h2>Статические маршруты</h2>
4 <h2>Статические маршруты</h2>
5 <p>Характеризуются тем, что адрес совпадает с самим маршрутом. Например, account/profile/edit. Несмотря на то, что адрес один, у разных пользователей он будет отображать разные данные, зависящие от того, кто сейчас авторизован.</p>
5 <p>Характеризуются тем, что адрес совпадает с самим маршрутом. Например, account/profile/edit. Несмотря на то, что адрес один, у разных пользователей он будет отображать разные данные, зависящие от того, кто сейчас авторизован.</p>
6 <h2>Динамические маршруты</h2>
6 <h2>Динамические маршруты</h2>
7 <p>А что, если у нас есть адреса, которые обозначают одно и тоже, но содержат параметр. Типичный пример /users/5. Без особого труда можно понять, что по этой ссылке мы получим информацию о пользователе с номером 5. Но тогда возникает вопрос: если у нас в базе тысячи пользователей, нам придётся определять тысячи маршрутов?</p>
7 <p>А что, если у нас есть адреса, которые обозначают одно и тоже, но содержат параметр. Типичный пример /users/5. Без особого труда можно понять, что по этой ссылке мы получим информацию о пользователе с номером 5. Но тогда возникает вопрос: если у нас в базе тысячи пользователей, нам придётся определять тысячи маршрутов?</p>
8 <p>К счастью, нет, здесь нам на помощь приходят регулярные выражения. Создаётся один маршрут, который выглядит примерно так: ^/users/(\w+). А дальше нужно просто сопоставить это регулярное выражение со строкой запроса. Другими словами, мы определили один единственный маршрут, который покрывает подобные ссылки:</p>
8 <p>К счастью, нет, здесь нам на помощь приходят регулярные выражения. Создаётся один маршрут, который выглядит примерно так: ^/users/(\w+). А дальше нужно просто сопоставить это регулярное выражение со строкой запроса. Другими словами, мы определили один единственный маршрут, который покрывает подобные ссылки:</p>
9 <p>/users/4 /users/1234 /users/3 /users/robocop</p>
9 <p>/users/4 /users/1234 /users/3 /users/robocop</p>
10 <p>После этого момента становится понятно, что процесс роутинга - это чуть сложнее, чем просто большой if/switch. В будущем мы начнём работать с фреймворками, в которых роутинг является одной из основных подсистем. Это справедливо для всех web-фреймворков на всех языках.</p>
10 <p>После этого момента становится понятно, что процесс роутинга - это чуть сложнее, чем просто большой if/switch. В будущем мы начнём работать с фреймворками, в которых роутинг является одной из основных подсистем. Это справедливо для всех web-фреймворков на всех языках.</p>
11 <p>Как правило, фреймворки предоставляют более высокоуровневый способ работы с роутами. То есть, вы пишете не сырые регулярные выражения, а строки с плейсхолдерами: /users/:id. Эти строки внутри заменяются на регулярные выражения и сопоставляются с запрашиваемыми адресами. Плейсхолдеры, в подавляющем большинстве фреймворков, заменяются на группу \w+. Эта группа не включает в себя / и требует обязательного наличия хотя бы одного символа. Это значит, что следующие маршруты не подходят под маршрут /users/:id:</p>
11 <p>Как правило, фреймворки предоставляют более высокоуровневый способ работы с роутами. То есть, вы пишете не сырые регулярные выражения, а строки с плейсхолдерами: /users/:id. Эти строки внутри заменяются на регулярные выражения и сопоставляются с запрашиваемыми адресами. Плейсхолдеры, в подавляющем большинстве фреймворков, заменяются на группу \w+. Эта группа не включает в себя / и требует обязательного наличия хотя бы одного символа. Это значит, что следующие маршруты не подходят под маршрут /users/:id:</p>
12 <p>/users /users/4/photos /users/my/d</p>
12 <p>/users /users/4/photos /users/my/d</p>
13 <p>В нашем сервере мы реализовали следующий способ работы роутера. Отдельно описывается объект, содержащий правила роутинга (как ключи) и обработчики маршрутов (как значения):</p>
13 <p>В нашем сервере мы реализовали следующий способ работы роутера. Отдельно описывается объект, содержащий правила роутинга (как ключи) и обработчики маршрутов (как значения):</p>
14 <p>Обратите внимание на важную деталь. Метод http тоже является частью роутинга. Для GET- и POST-запросов на /users будет использоваться два роута. Это связано с большим количеством причин, одной из которых является семантика http. А вот параметры запроса (например, /users?name=Tirion) не являются частью процесса маршрутизации (при таком роутинге, как выше). Они уже используются внутри обработчиков на ваше усмотрение.</p>
14 <p>Обратите внимание на важную деталь. Метод http тоже является частью роутинга. Для GET- и POST-запросов на /users будет использоваться два роута. Это связано с большим количеством причин, одной из которых является семантика http. А вот параметры запроса (например, /users?name=Tirion) не являются частью процесса маршрутизации (при таком роутинге, как выше). Они уже используются внутри обработчиков на ваше усмотрение.</p>
15 <p>Также имеет значение порядок, в котором заданы маршруты. Поэтому первыми должны идти статические и наиболее конкретизированные маршруты, а в конце более общие. Это правило справедливо в том случае, если есть пересечения.</p>
15 <p>Также имеет значение порядок, в котором заданы маршруты. Поэтому первыми должны идти статические и наиболее конкретизированные маршруты, а в конце более общие. Это правило справедливо в том случае, если есть пересечения.</p>
16 <p>Ещё остаётся работа с ошибками, такими как "страница не найдена". Здесь уже возможны варианты. Некоторые фреймворки обрабатывают эту ситуацию отдельно, проверяя, что ни один маршрут не совпал с запрошенным адресом, и выполняя специальный обработчик для этой ситуации. В других достаточно определить в самом конце маршрут *, в который попадет всё, что не попало в другие места. И из обработчика этого роута можно делать всё, что нужно для правильного отображения ошибки.</p>
16 <p>Ещё остаётся работа с ошибками, такими как "страница не найдена". Здесь уже возможны варианты. Некоторые фреймворки обрабатывают эту ситуацию отдельно, проверяя, что ни один маршрут не совпал с запрошенным адресом, и выполняя специальный обработчик для этой ситуации. В других достаточно определить в самом конце маршрут *, в который попадет всё, что не попало в другие места. И из обработчика этого роута можно делать всё, что нужно для правильного отображения ошибки.</p>
17 <p>Пример простого способа обрабатывать маршруты:</p>
17 <p>Пример простого способа обрабатывать маршруты:</p>
18 <h2>Соглашения</h2>
18 <h2>Соглашения</h2>
19 <p>В web-разработке существует понятие CRUD (<em>в русскоязычной среде говорят "круд"</em>), которое расшифровывается как CREATE, READ, UPDATE, DELETE. И самое простое и базовое, что делают разработчики - это круды. Например, любой административный интерфейс (админка сайта) - это большой набор разных крудов для всевозможных сущностей: круд постов в блог, круд товаров и так далее.</p>
19 <p>В web-разработке существует понятие CRUD (<em>в русскоязычной среде говорят "круд"</em>), которое расшифровывается как CREATE, READ, UPDATE, DELETE. И самое простое и базовое, что делают разработчики - это круды. Например, любой административный интерфейс (админка сайта) - это большой набор разных крудов для всевозможных сущностей: круд постов в блог, круд товаров и так далее.</p>
20 <p>Существуют соглашения о том, как грамотно делать круды с точки зрения маршрутизации. Они включают в себя особенности семантики http.</p>
20 <p>Существуют соглашения о том, как грамотно делать круды с точки зрения маршрутизации. Они включают в себя особенности семантики http.</p>
21 <p>GET /users # список POST /users # создание GET /users/10 # просмотр PATCH /users/10 # обновление DELETE /users/10 # удаление GET /users/10/photos # список фотографий</p>
21 <p>GET /users # список POST /users # создание GET /users/10 # просмотр PATCH /users/10 # обновление DELETE /users/10 # удаление GET /users/10/photos # список фотографий</p>