Middlewares
Fast App ships with a collection of route middleware that help you compose behaviour around your handlers. Each middleware is applied through the @middleware decorator and receives the fully-bound handler arguments. This section covers four core middlewares you are likely to use in production.
AuthorizeMiddleware
Use AuthorizeMiddleware to check abilities before executing a handler. It delegates to the authenticated user's authorize method and supports either class-level or instance-level checks.
@middleware(AuthorizeMiddleware("update", "post"))
async def update_post(post: Post):
...
@middleware(AuthorizeMiddleware("create", Post))
async def create_post():
...
- Resolves the referenced target either by name (from bound kwargs) or class.
- Raises
UnauthorizedExceptionwhen the user is missing or the policy denies. - Ideal companion to
ModelBindingMiddlewareso instance checks receive the already-bound model.
BelongsToMiddleware
BelongsToMiddleware ensures relational integrity between two bound models. It is particularly useful for nested resources where both parent and child models are injected into the handler.
@middleware(BelongsToMiddleware("organisation_member", "organisation"))
async def show_invitation(
organisation: Organisation,
organisation_member: OrganisationMember,
):
...
- Verifies that the child model's foreign key matches the parent's identifier.
- Supports custom
foreign_keyandparent_keyparameters when naming differs. - Raises
NotFoundExceptionto avoid leaking the existence of other tenants' data.
EtagMiddleware
EtagMiddleware adds HTTP caching semantics to JSON responses by computing a SHA1 digest of the serialised body and comparing it with the incoming If-None-Match header.
@middleware(EtagMiddleware())
async def list_posts():
return PostsResource(await Post.all())
- Returns
304 Not Modifiedwhen the computed ETag matches the request header. - Automatically sets the
ETagresponse header on cacheable responses. - Keeps handlers unchanged; simply wrap the existing route.
ThrottleMiddleware
ThrottleMiddleware provides per-identity request limiting with a configurable window and request count.
@middleware(ThrottleMiddleware(limit=60, window_seconds=60))
async def sensitive_action():
...
- Identifies clients via the authenticated user's id or, as a fallback, their IP address.
- Uses Redis-backed counters to track request volume.
- Raises
TooManyRequestsExceptionwhen the limit is exceeded, returning a429response.
Combine these middlewares as needed to layer authorisation, data protection, performance, and rate limiting policies on a per-route basis.