Skip to content

Instantly share code, notes, and snippets.

@Villenny
Created August 13, 2020 19:26
Show Gist options
  • Save Villenny/ea50501929301b5c1924be8e029e454b to your computer and use it in GitHub Desktop.
Save Villenny/ea50501929301b5c1924be8e029e454b to your computer and use it in GitHub Desktop.
Build a chain of http.HandlerFuncs in go
package httpServer
import (
"net/http"
)
/*
GIVEN MIDDLEWARES TO WIRE IN COMPONENTS LIKE:
func RequestIDMiddleware(makeTimeBasedUUIDFn func() string, next http.HandlerFunc) http.HandlerFunc {
fn := func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
requestID := makeTimeBasedUUIDFn()
ctx = context.WithValue(ctx, ContextKeyRequestID, requestID)
w.Header().Set("Request-ID", requestID)
next(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
EXAMPLE
handler := (&HandlerChain{}).
Do(func(chain http.HandlerFunc) http.HandlerFunc {
return RequestIDMiddleware(t.makeTimeBasedUUIDFn, chain)
}).
Do(func(chain http.HandlerFunc) http.HandlerFunc {
return ParamsMiddleware(chain)
}).
Finally(router)
*/
type HandlerChain struct {
handlerFns []func(next http.HandlerFunc) http.HandlerFunc
}
func (t *HandlerChain) Do(fn func(next http.HandlerFunc) http.HandlerFunc) *HandlerChain {
t.handlerFns = append(t.handlerFns, fn)
return t
}
func (t *HandlerChain) Finally(handler http.Handler) http.Handler {
h := handler.ServeHTTP
for i := len(t.handlerFns) - 1; i >= 0; i -= 1 {
h = t.handlerFns[i](h)
}
return http.HandlerFunc(h)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment