Middleware¶
A middleware is an indexed monadic action transforming one Conn
to another Conn
. It operates in some base monad m
, and is
indexed by i
and o
, the input and output Conn types of the
middleware action.
newtype Middleware m i o a = ...
The input and output type parameters are used to ensure that a Conn is transformed, and that side-effects are performed, correctly, throughout the middleware chain.
Being able to parameterize Middleware
with some type m
, you can
customize the chain depending on the needs of your middleware and
handlers. Applications can use monad transformers to track state,
provide configuration, gather metrics, and much more, in the chain of
middleware.
Middleware are composed using ibind
, the indexed monadic version of
bind
. The simplest way of composing middleware is by chaining them
with :*>
, from Control.IxMonad
. See
haskell-indexed-monad
for more information.
writeStatus statusOK
:*> closeHeaders
:*> respond "We're composing middleware!"
If you want to feed the return value of one middleware into another, use
:>>=
, the infix operator alias for mbind
.
getUser :>>= renderUser
You can also rebind the do block syntax to use ibind
instead of
regular bind
.
do
user <- getUser
writeStatus statusOK
closeHeaders
respond ("User: " <> user.name)
where bind = ibind