Маршрутизация
Falcon маршрутизирует входящие запросы к ресурсам на основе набора шаблонов URI. Если путь, запрошенный клиентом, соответствует шаблону для данного маршрута, запрос передаётся связанному ресурсу для обработки.
Если ни один маршрут не соответствует запросу, управление передаётся по умолчанию обработчику, который просто вызывает экземпляр HTTPNotFound. Обычно это приводит к отправке клиенту ответа 404.
Вот быстрый пример, демонстрирующий, как все части работают вместе:
import json
import falcon
class ImagesResource(object):
def on_get(self, req, resp):
doc = {
'images': [
{
'href': '/images/1eaf6ef1-7f2d-4ecc-a8d5-6e8adba7cc0e.png'
}
]
}
# Create a JSON representation of the resource
resp.body = json.dumps(doc, ensure_ascii=False)
# The following line can be omitted because 200 is the default
# status returned by the framework, but it is included here to
# illustrate how this may be overridden as needed.
resp.status = falcon.HTTP_200
api = application = falcon.API()
images = ImagesResource()
api.add_route('/images', images)
Маршрутизатор по умолчанию
По умолчанию Falcon использует движок маршрутизации, основанный на дереве решений, которое сначала компилируется в код Python, а затем оценивается во время выполнения.
Метод add_route() используется для связывания шаблона URI с ресурсом. Falcon затем сопоставляет входящие запросы с ресурсами на основе этих шаблонов.
По умолчанию Falcon использует классы Python для представления ресурсов. На практике эти классы действуют как контроллеры в вашем приложении. Они преобразуют входящий запрос в одно или несколько внутренних действий, а затем формируют ответ клиенту на основе результатов этих действий. (См. также: Учебник: Создание ресурсов)
┌────────────┐
request → │ │
│ Resource │ ↻ Orchestrate the requested action
│ Controller │ ↻ Compose the result
response ← │ │
└────────────┘
Каждый класс ресурса определяет различные методы «ответчика», по одному для каждого HTTP-метода, который ресурс поддерживает. Имена ответчиков начинаются с on_ и названы в соответствии с тем, какой HTTP-метод они обрабатывают, как в on_get(), on_post(), on_put(), и т. д.
Примечание
Если ваш ресурс не поддерживает определённый HTTP-метод, просто опустите соответствующий метод ответчика, и Falcon будет использовать метод ответчика по умолчанию, который вызывает экземпляр HTTPMethodNotAllowed, когда запрашивается этот метод. Обычно это приводит к отправке клиенту ответа 405.
Ответчики должны всегда определять как минимум два аргумента для получения объектов Request и Response, соответственно:
def on_post(self, req, resp):
pass
Объект Request представляет собой входящий HTTP-запрос. Он предоставляет свойства и методы для проверки заголовков, параметров строки запроса и других метаданных, связанных с запросом. Также предоставляется объект потока, похожий на файл, для чтения любых данных, включённых в тело запроса.
Объект Response представляет собой HTTP-ответ приложения на вышеупомянутый запрос. Он предоставляет свойства и методы для установки статуса, заголовков и данных тела. Объект Response также предоставляет свойство, подобное словарю, context, для передачи произвольных данных методам хуков и промежуточному программному обеспечению.
Примечание
Вместо непосредственного управления объектом Response, ответчик может вызвать экземпляр либо HTTPError, либо HTTPStatus. Falcon преобразует эти исключения в соответствующие HTTP-ответы. В качестве альтернативы, вы можете обработать их самостоятельно с помощью add_error_handler().
В дополнение к стандартным req и resp параметрам, если шаблон маршрута содержит выражения полей, любой ответчик, который хочет получать запросы для этого маршрута, должен принимать аргументы, именованные по именам соответствующих полей, определённых в шаблоне.
Выражение поля состоит из имени поля в квадратных скобках. Например, с учётом следующего шаблона:
/user/{name}
PUT-запрос к «/user/kgriffs» будет маршрутизирован к:
def on_put(self, req, resp, name):
pass
Поскольку имена полей соответствуют именам аргументов в методах ответчика, они должны быть допустимыми идентификаторами Python.
Отдельные сегменты пути могут содержать одно или несколько выражений поля, и поля не обязательно должны охватывать весь сегмент пути. Например:
/repos/{org}/{repo}/compare/{usr0}:{branch0}...{usr1}:{branch1}
/serviceRoot/People('{name}')
(См. также учебник Falcon для дополнительных примеров и пошагового руководства по настройке маршрутов в контексте примера приложения.)
Преобразователи полей
По умолчанию Falcon поддерживает использование преобразователей полей для преобразования значения поля шаблона URI. Преобразователи полей также могут выполнять простую проверку ввода. Например, следующий шаблон URI использует преобразователь int для преобразования значения tid в Python int, но только если оно содержит ровно восемь цифр:
/teams/{tid:int(8)}
Если значение неверно сформировано и не может быть преобразовано, Falcon отклонит запрос с ответом 404 клиенту.
Преобразователи инициализируются с указанием аргумента, заданного в выражении поля. Эти спецификации следуют стандартной синтаксической конструкции Python для передачи аргументов. Например, комментарии в следующем коде показывают, как преобразователь был бы инициализирован при различных спецификациях аргументов в шаблоне URI:
# IntConverter()
api.add_route(
'/a/{some_field:int}',
some_resource
)
# IntConverter(8)
api.add_route(
'/b/{some_field:int(8)}',
some_resource
)
# IntConverter(8, min=10000000)
api.add_route(
'/c/{some_field:int(8, min=10000000)}',
some_resource
)
Встроенные преобразователи
| Идентификатор | Класс | Пример |
|---|---|---|
int | IntConverter | /teams/{tid:int(8)} |
uuid | UUIDConverter | /diff/{left:uuid}...{right:uuid} |
dt | DateTimeConverter | /logs/{day:dt("%Y-%m-%d")} |
-
class falcon.routing.IntConverter(num_digits=None, min=None, max=None)[source] -
Преобразует значение поля в целое число.
Идентификатор:
intКлючевые аргументы:
-
class falcon.routing.UUIDConverter[source] -
Преобразует значение поля в uuid.UUID.
Идентификатор:
uuidДля преобразования значение поля должно состоять из строки из 32 шестнадцатеричных цифр, как определено в RFC 4122, раздел 3. Тем не менее, дефисы и префикс URN являются необязательными.
-
class falcon.routing.DateTimeConverter(format_string='%Y-%m-%dT%H:%M:%SZ')[source] -
Преобразует значение поля в дату и время.
Идентификатор:
dtКлючевые аргументы: format_string (str) – Строка, используемая для разбора значения поля в дату и время. Поддерживаются любые форматы, распознаваемые функцией strptime() (по умолчанию '%Y-%m-%dT%H:%M:%SZ').
Пользовательские преобразователи
Пользовательские преобразователи могут быть зарегистрированы через опцию маршрутизатора converters. Преобразователь — это просто класс, реализующий интерфейс BaseConverter:
-
class falcon.routing.BaseConverter[source] -
Абстрактный базовый класс для преобразователей полей шаблонов URI.
Пользовательские маршрутизаторы
Пользовательский движок маршрутизации может быть указан при создании экземпляра falcon.API(). Например:
router = MyRouter() api = API(router=router)
Пользовательские маршрутизаторы могут наследоваться от стандартного движка CompiledRouter или реализовывать совершенно другую стратегию маршрутизации (например, основанную на объектах).
Пользовательский маршрутизатор — это любой класс, реализующий следующий интерфейс:
class MyRouter(object):
def add_route(self, uri_template, resource, **kwargs):
"""Adds a route between URI path template and resource.
Args:
uri_template (str): A URI template to use for the route
resource (object): The resource instance to associate with
the URI template.
Keyword Args:
suffix (str): Optional responder name suffix for this
route. If a suffix is provided, Falcon will map GET
requests to ``on_get_{suffix}()``, POST requests to
``on_post_{suffix}()``, etc. In this way, multiple
closely-related routes can be mapped to the same
resource. For example, a single resource class can
use suffixed responders to distinguish requests for
a single item vs. a collection of those same items.
Another class might use a suffixed responder to handle
a shortlink route in addition to the regular route for
the resource.
**kwargs (dict): Accepts any additional keyword arguments
that were originally passed to the falcon.API.add_route()
method. These arguments MUST be accepted via the
double-star variadic pattern (**kwargs), and ignore any
unrecognized or unsupported arguments.
"""
def find(self, uri, req=None):
"""Search for a route that matches the given partial URI.
Args:
uri(str): The requested path to route.
Keyword Args:
req(Request): The Request object that will be passed to
the routed responder. The router may use `req` to
further differentiate the requested route. For
example, a header may be used to determine the
desired API version and route the request
accordingly.
Note:
The `req` keyword argument was added in version
1.2. To ensure backwards-compatibility, routers
that do not implement this argument are still
supported.
Returns:
tuple: A 4-member tuple composed of (resource, method_map,
params, uri_template), or ``None`` if no route matches
the requested path.
"""
Стандартный маршрутизатор
-
class falcon.routing.CompiledRouter[source] -
Быстрый маршрутизатор URI, который компилирует свою логику маршрутизации в код Python.
Как правило, вам не нужно использовать этот класс маршрутизатора напрямую, поскольку экземпляр создается по умолчанию при инициализации класса falcon.API.
Маршрутизатор обрабатывает пути URI как дерево сегментов URI и выполняет поиск, проверяя URI один сегмент за раз. Вместо интерпретации дерева маршрута для каждого поиска он генерирует встроенный, специализированный код Python для выполнения поиска, затем компилирует этот код. Это делает обработку маршрутов очень быстрой.
-
add_route(uri_template, resource, **kwargs)[source] -
Добавляет маршрут между шаблоном пути URI и ресурсом.
Этот метод можно переопределить для настройки того, как добавляется маршрут.
Параметры: Ключевые аргументы: suffix (str) – Необязательное суффиксное имя ответчика для этого маршрута. Если суффикс указан, Falcon будет сопоставлять запросы GET с
on_get_{suffix}(), запросы POST сon_post_{suffix}(), и т. д. Таким образом, несколько тесно связанных маршрутов можно сопоставить с одним и тем же ресурсом. Например, один класс ресурса может использовать суффиксные ответчики для различения запросов на один элемент и коллекции этих же элементов. Другой класс может использовать суффиксный ответчик для обработки маршрута сокращенной ссылки помимо обычного маршрута для ресурса.
-
find(uri, req=None)[source] -
Поиск маршрута, соответствующего заданному частичному URI.
Параметры: uri (str) – Запрашиваемый путь для маршрутизации. Ключевые аргументы: req (Request) – Объект запроса, который будет передан ответчику маршрута. В настоящее время значение этого аргумента игнорируется CompiledRouter. Маршрутизация основана только на пути.Возвращает: - Кортеж из 4 элементов, состоящий из (ресурс, метод_карта,
- параметры, шаблон_uri), или
Noneесли ни один маршрут не соответствует запрошенному пути.
Тип возвращаемого значения: tuple
-
map_http_methods(resource, **kwargs)[source] -
Сопоставление HTTP-методов (например, GET, POST) с методами объекта ресурса.
Этот метод вызывается из
add_route()и может быть переопределен для предоставления стратегии пользовательского сопоставления.Параметры: resource (экземпляр) – Объект, представляющий ресурс REST. По умолчанию сопоставляет HTTP-метод GETсon_get(),POSTсon_post(), и т. д. Если какие-либо HTTP-методы не поддерживаются вашим ресурсом, просто не определяйте соответствующие обработчики запросов, и Falcon сделает все правильно.Ключевые аргументы: suffix (str) – Необязательное суффиксное имя ответчика для этого маршрута. Если суффикс указан, Falcon будет сопоставлять запросы GET с on_get_{suffix}(), запросы POST сon_post_{suffix}(), и т. д. Таким образом, несколько тесно связанных маршрутов можно сопоставить с одним и тем же ресурсом. Например, один класс ресурса может использовать суффиксные ответчики для различения запросов на один элемент и коллекции этих же элементов. Другой класс может использовать суффиксный ответчик для обработки маршрута сокращенной ссылки помимо обычного маршрута для ресурса.
-
Утилиты маршрутизации
Модуль falcon.routing содержит следующие утилиты, которые могут использоваться пользовательскими движками маршрутизации.
-
falcon.routing.map_http_methods(resource, suffix=None)[source] -
Сопоставляет HTTP-методы (например, GET, POST) с методами объекта ресурса.
Параметры: resource – Объект с методами responder, следующими соглашению об именовании on_*, которые соответствуют каждому методу, поддерживаемому ресурсом. Например, если ресурс поддерживает GET и POST, он должен определить on_get(self, req, resp)иon_post(self, req, resp).Ключевые аргументы: suffix (str) – Необязательное окончание имени обработчика для данного маршрута. Если указан суффикс, Falcon будет сопоставлять запросы GET с on_get_{suffix}(), запросы POST сon_post_{suffix}(), и так далее.Возвращает: Сопоставление HTTP-методов с явно определенными обработчиками ресурса. Тип возвращаемого значения: dict
-
falcon.routing.set_default_responders(method_map)[source] -
Сопоставляет HTTP-методы, не определенные явно для ресурса, со стандартными обработчиками.
Параметры: method_map – Словарь с HTTP-методами, сопоставленными с обработчиками, явно определенными в ресурсе.
-
falcon.routing.compile_uri_template(template)[source] -
Компилирует заданную строку шаблона URI в соответствие с шаблоном поиска.
Эта функция может использоваться для построения пользовательских механизмов маршрутизации, которые итерируют список возможных маршрутов, пытаясь сопоставить входящий запрос с откомпилированной регулярной выражением для каждого маршрута.
Каждое поле преобразуется в именованную группу, так что при нахождении совпадения поля могут быть легко извлечены с помощью
re.MatchObject.groupdict().Эта функция не поддерживает более гибкий синтаксис шаблонов, используемый в стандартном маршрутизаторе. Поддерживаются только простые пути с выражениями полей в скобках. Например:
/ /books /books/{isbn} /books/{isbn}/characters /books/{isbn}/characters/{name}Также обратите внимание, что если шаблон содержит символ слеша в конце, он будет удален для нормализации логики маршрутизации.
Параметры: template (str) – Шаблон для компиляции. Обратите внимание, что имена полей ограничены символами ASCII a-z, A-Z и символом подчеркивания. Возвращает: (template_field_names, template_regex) Тип возвращаемого значения: tuple
© 2019 by Falcon contributors
Licensed under the Apache License, Version 2.0.
https://falcon.readthedocs.io/en/2.0.0/api/routing.html