Маршруты могут быть скомбинированы с помощью "составных" типов (см. таблицу 5.2). Такие типы маршрутов позволяют определить сколь угодно сложные правила маршрутизации URL.
| Тип маршрута | Описание |
|---|---|
| SimpleRouteStack | Объединяет различные типы маршрутов в список с приоритетами. |
| TreeRouteStack | Объединяет различные типы маршрутов в древовидную структуру. |
| Part | Объединяет различные типы маршрутов в поддерево. |
| Chain | Объединяет различные типы маршрутов в цепь (вырожденное поддерево). |
TreeRouteStack и SimpleRouteStack используются как типы маршрутов "верхнего уровня".
SimpleRouteStack позволяет организовать различные маршруты в список по степени важности.
TreeRouteStack позволяет вложить один маршрут в другой, формируя "дерево".
На рисунке 5.2 изображена диаграмма наследования классов маршрутов.
Figure 5.2. Диаграмма наследования классов маршрутов
Как видите, все классы маршрутов наследуются от интерфейса RouteInterface (мы
детально изучим этот интерфейс в разделе Написание своего типа маршрута позже
в этой главе). Класс SimpleRouteStack - родительский для класса TreeRouteStack, который
наследует поведение SimpleRouteStack (объединение маршрутов в список с приоритетами) и
расширяет его (объединение маршрутов в поддеревья). Классы Part и Chain
наследуются от класса TreeRouteStack и используются TreeRouteStack внутренне для построения
поддеревьев и цепей дочерних маршрутов.
Тип SimpleRouteStack позволяет объединить различные маршруты в список по степени важности.
Пример такого списка вы можете увидеть в стеке маршрутов в левой части рисунка 5.3.
Этот список содержит несколько маршрутов Literal и несколько маршрутов Segment.
При сопоставлении с HTTP-запросом, SimpleRouteStack проходит через список
маршрутов и пробует сопоставить каждый маршрут по очереди. Каждый маршрут в списке имеет свой приоритет;
маршруты с более высоким приоритетом обрабатываются первыми. Просмотр заканчивается, как только какой-либо
маршрут сопоставляется с HTTP-запросом. Если не удается сопоставить ни один маршрут, выдается ошибка "not found".
Рисунок 5.3. Пример SimpleRouteStack (слева) и TreeRouteStack (справа)
Класс TreeRouteStack расширяет SimpleRouteStack. Это означает, что помимо возможности
объединения маршрутов в список с приоритетами, он также может вставить маршруты в поддеревья
и цепи. Пример этого класса представлен в правой части рисунка 5.3.
Список состоит из одного маршрута Literal, цепи маршрутов Literal и Segment и
поддерева, состоящего из двух ветвей: ветви, содержащий один маршрут Segment и
ветви, состоящей из маршрутов Scheme, Hostname и Segment.
TreeRouteStack выполняет сопоставление запроса следующим образом. Он проходит по пунктам списка с приоритетами (обозначены пунктирными линиями на рисунке 5.3), начиная с маршрутов с наивысшим приоритетом.
Если какой-либо из пунктов - это маршрут Chain или Part, TreeRouteStack обрабатывает этот вложенный маршрут от родительского
маршрута к дочерним. Если удается сопоставить родительский маршрут, анализируются дочерние (обозначены сплошными линиями). Вложенный маршрут
совпадает, если совпадает хотя бы один маршрут на каждом уровне дерева (или цепи).
Каждый маршрут в дереве (или цепи) занимает часть URL (рисунок 5.4). Родительский маршрут сопоставляется с первой частью URL, дочерний со следующей, и так до конца строки URL.