New on the blog: Writing Your Own Middleware in Wh...
# wheels-dev
p
New on the blog: Writing Your Own Middleware in Wheels 4.0. <blog.wheels.dev/posts/writing-custom-middleware-wheels-4|Full Post> The rate-limiting post covered using the built-in middleware. This one is the other half — authoring your own. It's a small surface that hides one lifecycle decision that will bite you if you miss it. What it covers: • The one-method contract —
handle(request, next)
returns a string; code before
next()
runs in, code after runs out. • Why
request
is NOT the CFML
request
scope (it's a
{params, route, pathInfo, method}
struct) and the Adobe CF scope-shadow trap that follows. • The lifecycle that changes everything: every middleware is a singleton shared across all concurrent requests for the app's lifetime — so any mutable state MUST be locked. Worked example with a
cflock
-guarded counter. • Short-circuiting — return a string WITHOUT calling
next()
to skip the controller (how RateLimiter does its 429 and Cors does OPTIONS). • Registration: global in config/settings.cfm vs route-scoped in config/routes.cfm, string-path vs object-instance, and why global always runs before route-scoped. Three worked components: a request timer, a thread-safe audit logger, and a maintenance gate.