Среднее ПО
Компоненты среднего ПО предоставляют способ выполнения логики до маршрутизации каждого запроса фреймворком, после маршрутизации каждого запроса, но перед вызовом целевого обработчика, или непосредственно перед возвратом ответа для каждого запроса. Компоненты регистрируются с параметром middleware при создании класса API Falcon.
Примечание
В отличие от хуков, методы среднего ПО применяются глобально ко всему API.
Интерфейс среднего ПО Falcon определен следующим образом:
class ExampleComponent(object):
def process_request(self, req, resp):
"""Process the request before routing it.
Note:
Because Falcon routes each request based on req.path, a
request can be effectively re-routed by setting that
attribute to a new value from within process_request().
Args:
req: Request object that will eventually be
routed to an on_* responder method.
resp: Response object that will be routed to
the on_* responder.
"""
def process_resource(self, req, resp, resource, params):
"""Process the request after routing.
Note:
This method is only called when the request matches
a route to a resource.
Args:
req: Request object that will be passed to the
routed responder.
resp: Response object that will be passed to the
responder.
resource: Resource object to which the request was
routed.
params: A dict-like object representing any additional
params derived from the route's URI template fields,
that will be passed to the resource's responder
method as keyword arguments.
"""
def process_response(self, req, resp, resource, req_succeeded):
"""Post-processing of the response (after routing).
Args:
req: Request object.
resp: Response object.
resource: Resource object to which the request was
routed. May be None if no route was found
for the request.
req_succeeded: True if no exceptions were raised while
the framework processed and routed the request;
otherwise False.
"""
Подсказка
Поскольку process_request выполняется до маршрутизации, если компонент изменяет req.path в методе process_request, фреймворк будет использовать изменённое значение для маршрутизации запроса.
Например:
# Route requests based on the host header. req.path = '/' + req.host + req.path
Подсказка
Метод process_resource вызывается только тогда, когда запрос соответствует маршруту к ресурсу. Чтобы принять меры, когда маршрут не найден, можно использовать sink вместо этого.
Подсказка
Для передачи данных из функции среднего ПО в функцию ресурса используйте объекты req.context и resp.context. Эти объекты контекста предназначены для хранения данных запроса и ответа, специфичных для вашего приложения, по мере его обработки фреймворком.
Методы process_request, process_resource и process_response каждого компонента выполняются иерархически, как стек, в соответствии с порядком списка, переданного с параметром middleware класса falcon.API. Например, если список объектов среднего ПО передан как [mob1, mob2, mob3], порядок выполнения следующий:
mob1.process_request
mob2.process_request
mob3.process_request
mob1.process_resource
mob2.process_resource
mob3.process_resource
<route to resource responder method>
mob3.process_response
mob2.process_response
mob1.process_response
Обратите внимание, что каждый компонент не обязательно должен реализовывать все process_* методы; в случае отсутствия одного из трёх методов, он рассматривается как noop в стеке. Например, если mob2 не реализовывал process_request, а mob3 не реализовывал process_response, порядок выполнения будет таким:
mob1.process_request
_
mob3.process_request
mob1.process_resource
mob2.process_resource
mob3.process_resource
<route to responder method>
_
mob2.process_response
mob1.process_response
Прерывание
Метод process_request среднего ПО может прервать дальнейшую обработку запроса, установив complete в значение True, например:
resp.complete = True
После возврата метода установка этого флага заставит фреймворк пропустить все оставшиеся методы process_request и process_resource, а также метод обработчика, к которому был маршрутизирован запрос. Однако любые методы process_response среднего ПО всё ещё будут вызваны.
Аналогичным образом, установка complete в значение True из метода process_resource прервёт дальнейшую обработку запроса на этом этапе.
Эта функция позволяет использовать случаи, когда ответ может быть предварительно сконструирован, например, при кэшировании.
Обработка исключений
Если один из методов process_request среднего ПО вызывает исключение, оно будет обработано в соответствии с типом исключения. Если тип совпадает с зарегистрированным обработчиком ошибок, этот обработчик будет вызван, а затем фреймворк начнёт разворачивать стек, пропуская любые нижние слои. Обработчик ошибок может сам вызвать экземпляр HTTPError или HTTPStatus, в этом случае фреймворк будет использовать последнее исключение для обновления объекта resp.
Примечание
По умолчанию фреймворк устанавливает два обработчика, один для HTTPError и один для HTTPStatus. Их можно переопределить с помощью add_error_handler().
В любом случае, фреймворк продолжит разворачивать стек среднего ПО. Например, если mob2.process_request вызовет ошибку, фреймворк выполнит стек следующим образом:
mob1.process_request
mob2.process_request
<skip mob1/mob2 process_resource>
<skip mob3.process_request>
<skip mob3.process_resource>
<skip route to resource responder method>
mob3.process_response
mob2.process_response
mob1.process_response
Как показано выше, по умолчанию все методы process_response будут выполнены, даже когда методы process_request, process_resource или обработчик ресурса вызывают ошибку. Это поведение контролируется аргументом ключевого слова класса API independent_middleware.
Наконец, если один из методов process_response вызовет ошибку или сам метод обработчика маршрутизированного on_* ресурса вызовет ошибку, исключение будет обработано аналогичным образом. Затем фреймворк выполнит любые оставшиеся компоненты среднего ПО в стеке.
© 2019 by Falcon contributors
Licensed under the Apache License, Version 2.0.
https://falcon.readthedocs.io/en/2.0.0/api/middleware.html