Skip to main content

route

When you define a route, you expose a resource through a specific path that clients can request. you then add an Endpoint on the route to determin what clients can do with the resource.

Take url https://dontclickme.com/users as an example, path /users would locate resource users.

Defining an route

from lihil import Route

users_route = Route("/users")

If you have existing lihil.Graph and lihil.MessageRegistry that you would like to use, put then in the route constructor.

This is useful if you keep dependencies and event listeners in separate files, example:

from project.users.deps import user_graph
from project.users.listeners import user_eventregistry

user_route = Route(graph=uesr_graph, registry=user_eventregistry)

You can also add middlewares to a route if you want them to apply only to that specific route.

from starlette.middleware.cors import CORSMiddleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware

Route(middlewares=[CORSMiddleware])
route.add_middleware(HTTPSRedirectMiddleware)

register endpoint to an route.

In previous dicussion, we expose create_user as an endpoint for POST request of users_route. we can also declare other http methods with similar syntax, this includes:

  • GET
  • POST
  • HEAD
  • OPTIONS
  • TRACE
  • PUT
  • DELETE
  • PATCH
  • CONNECT

This means that an route can have 0-9 endpoints.

to expose a function for multiple http methods

  • apply multiple decorators to the function

  • or, equivalently, use Route.add_endpoint


users_route.add_endpoint("GET", "POST", ..., create_user)

Defining an sub-route

In previous discussion, we created a route for users, a collection of the user resource, to expose an specific user resource,

user_route = users_route.sub("{user_id}")

@user_route.get
async def get_user(user_id: str, limit: int = 1): ...

Here, we define a sub route of users_route, when we include an route into our Lihil, all of its sub-routes will also be included recursively.

Route are unique to path, thus, you might call it constructor with same path multiple times.

@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): ...

here both get_user and update_user are under the same route.

The root route

an route with path / is the root route, if not provided, root route is created with Lihil by default, anything registered via Lihil.{http method} is the under the root route.