The request lifecycle

What runs between a request arriving and a response leaving, and why in that order.

Bustan 0.0.2 introduces three extension points — guards, pipes and interceptors. Knowing the order they run in is most of knowing where to put code.

deniedinvalidraisedrequestmiddlewareroutingguardspipeshandlerinterceptorsresponseerror filterdeniedinvalidraisedrequestmiddlewareroutingguardspipeshandlerinterceptorsresponseerror filter

Why this order#

Middleware before routing. Middleware sees raw ASGI scope and does not know which handler will run — right for logging, tracing, compression.

Guards before pipes. Authorisation does not depend on parameters being well-formed. Validating input for a request you are about to reject wastes work and, worse, leaks information: careful 400s tell an unauthenticated caller which fields exist.

Pipes before the handler. By the time the handler runs, every value it receives has been coerced and checked. Handlers do no defensive parsing.

Interceptors around the handler. An interceptor wraps the call, so it sees both sides — the right place for timing, caching and response shaping.

Where to put what#

Concern Goes in
Request logging, tracing Middleware
"May this caller do this?" Guard
"Is this value usable?" Pipe
Timing, caching, envelopes Interceptor
Turning exceptions into responses Error filter

The tempting mistake#

Authorisation in a pipe. It works — a pipe can raise — and it puts the check next to the value it concerns.

But pipes run per parameter and only on parameters the handler declares. A route that takes no arguments runs no pipes and is silently unprotected. Guards run for every matched route regardless of signature, which is exactly the property an authorisation check needs.

Errors#

Anything raised in guards, pipes, the handler or interceptors reaches the error filter, which maps exceptions to responses. Built-in exceptions carry their status; anything else becomes a 500 with the detail logged, not returned.

That default is deliberate. A framework that echoes exception text by default will eventually echo a connection string.