package chain import "net/http" type ( Chain interface { Append(middleware ...Middleware) Chain Prepend(middleware ...Middleware) Chain Then(http.Handler) http.Handler ThenFunc(fn http.HandlerFunc) http.Handler } Middleware func(http.Handler) http.Handler chain struct { middlewares []Middleware } ) func New(middlewares ...Middleware) Chain { return chain{ middlewares: append([]Middleware(nil), middlewares...), } } func (c chain) Append(middleware ...Middleware) Chain { return chain{ middlewares: join(c.middlewares, middleware), } } func (c chain) Prepend(middleware ...Middleware) Chain { return chain{ middlewares: join(middleware, c.middlewares), } } func (c chain) Then(h http.Handler) http.Handler { if h == nil { h = http.DefaultServeMux } for i := range c.middlewares { h = c.middlewares[len(c.middlewares)-i-1](h) } return h } func (c chain) ThenFunc(fn http.HandlerFunc) http.Handler { if fn == nil { return c.Then(nil) } return c.Then(fn) } func join(a, b []Middleware) []Middleware { mids := make([]Middleware, 0, len(a)+len(b)) mids = append(mids, a...) mids = append(mids, b...) return mids }