routes/api/ and
routes/pages/ automatically.
routes/api/users.py
Prefixes
Keep routes thin
Parse the request, call a service, return a response. A handler doing work that belongs in a service is reported byfeather check as the fat-route warning.
Services
Where business logic goes, with transactions handled for you.
Exceptions
Raise a typed exception and it becomes the right JSON response.
Redirecting after an action
Most actions end by sending the browser somewhere with a message.redirect_with_toast
does both, and works for an htmx request and a plain form post alike: htmx gets an
HX-Redirect, a normal request a 302, and the toast shows on the page that loads.
htmx_redirect(url) sends just the header.
Auth decorators
Every route should carry one, or declare itself public. A route with no auth decorator is reported as theunprotected-route warning. A deliberately public one carries a
# feather: public comment in its module.
See Authentication for the full decorator set.
Template filters, globals and error pages
Register app-wide helpers on thepage blueprint, in a module under routes/pages/, not
in app.py:
routes/pages/template_helpers.py
TestingConfig and never imports app.py, so anything
registered there exists when you run the app and is missing in every test. The blueprint’s
app_* hooks reach every app Feather builds from the project.