маршрут
Когда вы определяете маршрут, вы предоставляете ресурс через конкретный путь, который клиенты могут запросить. Затем вы добавляете Endpoint к маршруту, чтобы определить, что клиенты могут делать с ресурсом.
Возьмем URL https://dontclickme.com/users в качестве примера, путь /users будет указывать на ресурс users.
Определение маршрута
from lihil import Route
users_route = Route("/users")
Если у вас есть существующие lihil.Graph и lihil.MessageRegistry, которые вы хотели бы использовать, поместите их в конструктор маршрута.
Это полезно, если вы храните зависимости и слушатели событий в отдельных файлах, например:
from project.users.deps import user_graph
from project.users.listeners import user_eventregistry
user_route = Route(graph=uesr_graph, registry=user_eventregistry)
Вы также можете добавить middleware к маршруту, если хотите, чтобы они применялись только к этому конкретному маршруту.
from starlette.middleware.cors import CORSMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
Route(middlewares=[CORSMiddleware])
route.add_middleware(HTTPSRedirectMiddleware)
Регистрация endpoint'а в маршруте.
В предыдущем обсуждении мы предоставили create_user как endpoint для POST запроса users_route.
мы также можем объявить другие HTTP-методы с похожим синтаксисом, включая:
| Метод | Идемпотентный | Назначение | Пример |
|---|---|---|---|
GET | Да | Получить данные без изменения состояния сервера | @route.get |
POST | Нет | Отправить данные для создания ресурса или вызова действия | @route.post |
HEAD | Да | То же, что GET, но возвращает только заголовки | @route.head |
OPTIONS | Да | Обнаружить разрешенные методы и информацию о CORS | @route.options |
TRACE | Да | Отправить полученный запрос обратно (для отладки) | @route.trace |
PUT | Да | Заменить ресурс предоставленными данными | @route.put |
DELETE | Да | Удалить ресурс | @route.delete |
PATCH | Нет | Применить частичные изменения к ресурсу | @route.patch |
CONNECT | Нет | Установить туннель к серверу (например, HTTPS) | @route.connect |
Это означает, что маршрут может иметь 0-9 endpoint'ов.
чтобы предоставить функцию для нескольких HTTP-методов
-
применить несколько декораторов к функции
-
или, что эквивалентно, использовать
Route.add_endpoint
users_route.add_endpoint("GET", "POST", ..., create_user)
Определение подмаршрута
В предыдущем обсуждении мы создали маршрут для users, коллекции пользовательского ресурса,
чтобы предоставить конкретный пользовательский ресурс,
user_route = users_route.sub("{user_id}")
@user_route.get
async def get_user(user_id: str, limit: int = 1): ...
Здесь
мы определяем подмаршрут users_route, когда мы включаем маршрут в наш Lihil, все его подмаршруты также будут включены рекурсивно.
Route.sub идемпотентен, вы можете вызывать его с одним и тем же путем несколько раз.
@users_route.sub("{user_id}").get
async def get_user(user_id: str, limit: int = 1): ...
@users_route.sub("{user_id}").put
async def update_user(data: UserUpdate): ...
Здесь и get_user, и update_user находятся под одним и тем же маршрутом.
включение подмаршрутов
Для больших приложений обычно люди сначала создают подмаршруты, а затем включают их в родительские маршруты, для этого используйте Route.include_subroutes
parent = Route("/parent")
sub = Route("/sub")
parent.include_subroutes(sub)
assert parent.subroutes[0].path == "/parent/sub"
Разница между Route.sub и Route.include_subroutes заключается в том, что,
Route.subсоздает новый пустой маршрут на основе пути строкового типаRoute.include_subroutesрекурсивно включает существующие маршруты как подмаршруты, пересоздает их на основе их свойств (endpoint'ы, middleware и т.д.)
Рекомендуется создавать файл для каждого маршрута,
items = Route("/items")
@items.get
def list_items(): ...
@items.sub("/{item_id}").get
def get_item(item_id: str) :...
затем создать родительский маршрут в __init__.py папки и включить подмаршруты
from .items import items
carts = Route("/carts")
carts.include_subroutes(items)
Корневой маршрут
Маршрут с путем / является корневым маршрутом, если не предоставлен, корневой маршрут создается с Lihil по умолчанию, все, что зарегистрировано через Lihil.{http method}, находится под корневым маршрутом.
Следующие примеры функционально одинаковы
- использовать экземпляр
Lihilкак корневой маршрут
lhl = Lihil()
@lhl.get
async def hello():
return "hello, world"
- создать корневой маршрут, затем включить его в ваш экземпляр
Lihil
root = Route()
@root.get
async def hello():
return "hello, world"
lhl = Lihil(root)