Last active
August 29, 2015 14:03
-
-
Save larryfox/cfa0911c3633ed25f1f7 to your computer and use it in GitHub Desktop.
Functional middleware chaining in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package middleware | |
import "net/http" | |
// Middleware are just functions that accept an | |
// http.Handler and return an http.Handler | |
type Middleware func(http.Handler) http.Handler | |
// Chain composes any number of middleware to another. | |
// Middleware(a).Chain(b, c) | |
// is equvilant to | |
// Chain(a, b, c) | |
func (m Middleware) Chain(wares ...Middleware) Middleware { | |
return compose(m, Chain(wares...)) | |
} | |
// Apply calls the Middleware with the supplied Handler. | |
// Middleware(myMiddleware).Apply(myHandler) | |
// is equivlant to | |
// Middleware(myMiddleware)(myHandler) | |
// is equivlant to | |
// myMiddleware(myHandler) | |
func (m Middleware) Apply(x http.Handler) http.Handler { | |
return m(x) | |
} | |
// Chain composes any number of middleware together. | |
// Chain(a, b, c, d) | |
func Chain(wares ...Middleware) Middleware { | |
return foldr(compose, noop, wares...) | |
} | |
type combinator func(a, b Middleware) Middleware | |
func compose(a, b Middleware) Middleware { | |
return func(x http.Handler) http.Handler { | |
return a(b(x)) | |
} | |
} | |
func foldr(cmb combinator, acc Middleware, wares ...Middleware) Middleware { | |
if len(wares) == 0 { | |
return acc | |
} | |
return cmb(wares[0], foldr(cmb, acc, wares[1:]...)) | |
} | |
// noop Middleware. Used as the initial value for foldr | |
func noop(h http.Handler) http.Handler { | |
return h | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage…