Litestar's layered architecture allows you to declare parameters at multiple levels: the Litestar app, Router, Controller, and the individual route handler.
- App Level: Parameters declared on the
Litestar app (e.g., using CookieParameter) are extracted and validated at the application level. They can exist even if the route handler does not explicitly declare them. - Router Level: Parameters declared on a
Router (e.g., using HeaderParameter) apply to all routes within that router. If a handler re-declares the parameter using a type like FromHeader[str], it becomes required at the handler level. - Controller Level: Parameters declared on a
Controller (e.g., using QueryParameter) apply to all handlers in that controller. Handlers can re-declare these parameters to tighten constraints (e.g., changing lt=100 to lt=50). - Handler Level: Local parameters like
FromQuery, FromHeader, FromCookie, and FromPath are specific to the individual route function.
from typing import Annotated
from litestar import Litestar, get, Router, Controller
from litestar.enums import HTTPMethod
from litestar.params import CookieParameter, HeaderParameter, QueryParameter, FromHeader, FromQuery, FromPath
# 1. App Level: Cookie parameter 'special-cookie' (optional)
app = Litestar(
route=None,
parameters=[CookieParameter(name="special-cookie", annotation=str, required=False)]
)
# 2. Router Level: Header parameter 'MyHeader'
router = Router(
path="/router",
router_param=HeaderParameter(name="MyHeader", required=False),
route=get("/") # Handler re-declares it as required via FromHeader
)
# 3. Controller Level: Query parameter 'controller_param' with lt=100
class MyController(Controller):
path = "/controller"
parameters = [QueryParameter(name="controller_param", lt=100)]
@get("/")
def handler(
self,
# Tightening constraint to lt=50
controller_param: Annotated[int, QueryParameter(lt=50)],
# Local parameters
local_param: FromQuery[str],
path_param: FromPath[int]
) -> None:
pass