Router¶
Router является главным объектом, который связывает Esmerald с Gateway, WebSocketGateway и handlers.
Класс Router¶
Класс Router состоит из множества атрибутов, которые по умолчанию заполняются в приложении. Однако Esmerald также позволяет добавить дополнительные пользовательские маршрутизаторы или добавить приложение ChildEsmerald.
from pydantic import BaseModel
from esmerald import Esmerald, Gateway, post
class User(BaseModel):
name: str
email: str
@post("/create")
def create(data: User) -> User: ...
app = Esmerald(routes=[Gateway(handler=create)])
Основной класс Router
создается в приложении Esmerald
с заданными маршрутами и приложение запускается.
Info
При добавлении другого маршрутизатора в приложение доступны два варианта: пользовательские маршрутизаторы
и ChildEsmerald. В данном случае пользовательские маршрутизаторы
более ограничены, чем ChildEsmerald
.
Параметры¶
Все параметры и значения по умолчанию доступны в Router.
Warning
response_class
, response_cookies
, response_headers
, tags
и include_in_schema
не используются в
add_route, только при использовании ChildEsmerald.
Пользовательский маршрутизатор¶
Предположим, что существуют определенные подмодули customer в файле customers
, посвященном клиентам.
Существует три способа разделения маршрутов в приложении: с использованием Include,
ChildEsmerald или созданием другого маршрутизатора. Давайте сосредоточимся на последнем варианте.
from pydantic import BaseModel
from esmerald import Gateway, JSONResponse, Router, get, post
class Address(BaseModel):
address_line: str
street: str
post_code: str
class Customer(BaseModel):
name: str
email: str
address: Address
@post("/")
def create(data: Customer) -> JSONResponse:
return JSONResponse({"created": True})
@get("/{customer_id:int}")
async def get_customer(customer_id: int) -> JSONResponse:
return JSONResponse({"created": True})
router = Router(
path="/customers",
routes=[
Gateway("/", handler=get_customer),
Gateway("/create", handler=create),
],
)
Выше вы создали /application/apps/routers/customers.py
с необходимой информацией. Он не обязательно должен быть в одном файле,
вы можете создать совершенно отдельный пакет, только для управления customer.
Теперь вам нужно добавить новый пользовательский маршрутизатор в основное приложение.
from apps.routers.customers import router as customers_router
from esmerald import Esmerald
app = Esmerald()
app.add_router(customers_router)
Ваш маршрутизатор добавлен в основное приложение Esmerald.
Child Esmerald Application¶
Что это такое? Мы называем его ChildEsmerald
, но на самом деле это просто Esmerald, но под другим именем, в основном для удобства организации.
Check
Использование ChildEsmerald
или Esmerald
абсолютно одно и тоже, если вы хотите создать sub application
и предпочитаете использовать другой класс вместо Esmerald
для более удобной организации.
При организации маршрутов использование самого класса Router
может быть немного ограничивающим, поскольку существуют определенные атрибуты,
которые при использовании в экземпляре или Router
для передачи в add_route не будут учтены.
Пример:
response_class
response_cookies
response_headers
tags
include_in_schema
Это не ограничение и не ошибка, на самом деле это сделано намеренно, поскольку мы хотим сохранить целостность приложения.
Как это работает¶
Давайте используем тот же пример, что и в пользовательских маршрутизаторах с маршрутами и правилами, специфичными для клиентов.
from pydantic import BaseModel
from esmerald import ChildEsmerald, Gateway, JSONResponse, get, post
class Address(BaseModel):
address_line: str
street: str
post_code: str
class Customer(BaseModel):
name: str
email: str
address: Address
@post("/")
def create(data: Customer) -> JSONResponse:
return JSONResponse({"created": True})
@get("/{customer_id:int}")
async def get_customer(customer_id: int) -> JSONResponse:
return JSONResponse({"created": True})
router = ChildEsmerald(
routes=[
Gateway("/", handler=get_customer),
Gateway("/create", handler=create),
],
include_in_schema=...,
response_class=...,
response_headers=...,
response_cookies=...,
)
Поскольку ChildEsmerald
является представлением класса Esmerald,
мы можем передать ранее ограниченные параметры в пользовательском маршрутизаторе и все параметры,
доступные для Esmerald.
Вы можете добавить столько ChildEsmerald
, сколько захотите, ограничений нет.
Теперь в основном приложении:
from apps.routers.customers import router as customers_router
from esmerald import Esmerald, Include
app = Esmerald(routes=[Include("/customers", app=customers_router)])
Добавление вложенных приложений
from apps.routers.clients import router as clients_router
from apps.routers.customers import router as customers_router
from apps.routers.restrict import router as restrict_router
from esmerald import Esmerald, Include
app = Esmerald(
routes=[
Include("/customers", app=customers_router),
Include(
"/api/v1",
routes=[
Include("/clients", clients_router),
Include("/restrict", routes=[Include("/access", restrict_router)]),
],
),
]
)
Приведенный выше пример показывает, что вы даже можете добавить то же самое приложение внутри вложенных includes,
и для каждого include вы можете добавить уникальные permissions, middlewares,
обработчики исключений и зависимости, которые доступны для каждого экземпляра Include
.
Вариантов бесконечно много.
Note
С точки зрения организации, ChildEsmerald
имеет чистый подход к изоляции обязанностей и позволяет
рассматривать каждый модуль отдельно и просто добавлять его в основное приложение
в форме Include.
Tip
Рассматривайте ChildEsmerald
как независимый экземпляр Esmerald
.
Check
При добавлении приложения ChildEsmerald
или Esmerald
не забудьте добавить уникальный путь в базовый Include
,
таким образом вы можете быть уверены, что маршруты будут найдены правильно.
Утилиты¶
Объект Router
имеет ряд функций, которые могут быть полезны.
add_route¶
from esmerald import Esmerald
app = Esmerald()
app.add_route(
handler=...,
dependencies=...,
exception_handlers=...,
permissions=...,
middleware=...,
name=...,
interceptors=...,
include_in_schema=...,
)
Параметры¶
- name - Название маршрута.
- include_in_schema - Добавлять ли маршрут в схему OpenAPI.
- handler - HTTP обработчик.
- permissions - Список permissions для обслуживания входящих запросов приложения (HTTP и WebSockets).
- middleware - Список middleware выполняемых для каждого запроса. Middlewares из Include будут проверяться сверху вниз.
- interceptors - Список interceptors или Lilya Middleware, поскольку они оба внутренне преобразуются. Узнайте больше о Python Protocols.
- dependencies - Словарь строк и экземпляров Inject, позволяющих внедрить зависимости на уровне приложения.
- exception_handlers - Словарь типов исключений (или пользовательских исключений) и функций-обработчиков на верхнем уровне приложения.
Вызываемые обработчики исключений должны иметь вид
handler(request, exc) -> response
и могут быть как синхронными, так и асинхронными функциями.
add_websocket_route¶
from esmerald import Esmerald
app = Esmerald()
app.add_websocket_route(
handler=...,
dependencies=...,
exception_handlers=...,
permissions=...,
middleware=...,
interceptors=...,
name=...,
)
Параметры¶
- name - Название маршрута.
- Websocket handler - Websocket обработчик.
- permissions - Список permissions для обслуживания входящих запросов приложения (HTTP и WebSockets).
- interceptors - Список interceptors.
- middleware - Список middleware выполняемых для каждого запроса. Middlewares из Include будут проверяться сверху вниз. Или Lilya Middleware, поскольку они оба внутренне преобразуются. Узнайте больше о Python Protocols.
- dependencies - Словарь строк и экземпляров Inject, позволяющих внедрить зависимости на уровне приложения.
- exception_handlers - Словарь типов исключений (или пользовательских исключений) и функций-обработчиков на верхнем уровне приложения.
Вызываемые обработчики исключений должны иметь вид
handler(request, exc) -> response
и могут быть как синхронными, так и асинхронными функциями.
add_child_esmerald¶
from esmerald import ChildEsmerald, Esmerald, Gateway, get
@get()
async def home() -> str:
return "home"
child = ChildEsmerald(routes=[Gateway(handler=home, name="my-apiview")])
app = Esmerald()
app.add_child_esmerald(
path="/child",
child=child,
name=...,
middleware=...,
dependencies=...,
exception_handlers=...,
interceptors=...,
permissions=...,
include_in_schema=...,
deprecated=...,
security=...,
)
Параметры¶
- path - Путь для ChildEsmerald.
- child - Экземпляр ChildEsmerald.
- name - Название маршрута.
- Websocket handler - Websocket обработчик.
- permissions - Список permissions для обслуживания входящих запросов приложения (HTTP и WebSockets).
- interceptors - Список interceptors.
- middleware - Список middleware выполняемых для каждого запроса. Middlewares из Include будут проверяться сверху вниз. Или Lilya Middleware, поскольку они оба внутренне преобразуются. Узнайте больше о Python Protocols.
- dependencies - Словарь строк и экземпляров Inject, позволяющих внедрить зависимости на уровне приложения.
- exception_handlers - Словарь типов исключений (или пользовательских исключений) и функций-обработчиков на верхнем уровне приложения.
Вызываемые обработчики исключений должны иметь вид
handler(request, exc) -> response
и могут быть как синхронными, так и асинхронными функциями. - include_in_schema - Флаг, указывающий, следует ли включать ChildEsmerald в схему OpenAPI.
- deprecated - Флаг, указывающий, следует ли пометить ChildEsmerald как устаревший.