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