HandlerFunc signature:
Middleware type is an alias for HandlerFunc, so the two are interchangeable. Middleware and route handlers share the same type — a middleware is simply a handler that calls ctx.Next() to pass control to the next function in the chain.
How the chain works
When a request arrives, Lightning executes the handlers in order:- Global middleware (registered with
app.Use) - Group middleware (if the route belongs to a group)
- Route-level middleware (extra handlers passed to
Get,Post, etc.) - The final route handler
ctx.Next() to advance to the next one. You can run logic before ctx.Next() (pre-processing) and logic after it (post-processing).
Global middleware
Register middleware that runs for every request withapp.Use. You can pass multiple middlewares in a single call or chain multiple Use calls.
/, the execution order is:
Route-level middleware
Pass extra handler functions before the final handler toGet, Post, or any other method registration. These run only for that specific route.
Writing a custom middleware
Here is a complete auth middleware that validates a bearer token before allowing the request to proceed.If you want to abort the request (e.g. due to a failed auth check), return from the middleware without calling
ctx.Next(). Lightning will not advance the chain.Built-in middleware
Lightning ships two middleware functions you can use immediately.Logger
Logger() logs each request after it completes, reporting the remote address, method, status code, path, elapsed time, and user agent.
Logger calls ctx.Next() internally and logs on the way back, so it measures total handler time correctly.
Recovery
Recovery() catches any panic that occurs downstream, writes a stack trace to stderr, and returns a 500 response. This prevents a single panicking handler from crashing the entire server.
Using both together
lightning.DefaultApp() is a convenience constructor that registers Logger and Recovery for you:
Complete example
- Global middleware
- Route-level middleware