Skip to content

Instantly share code, notes, and snippets.

@srishanbhattarai
Last active January 22, 2018 19:59
Show Gist options
  • Save srishanbhattarai/f3877756108d4a8063fcc3468b5e6d73 to your computer and use it in GitHub Desktop.
Save srishanbhattarai/f3877756108d4a8063fcc3468b5e6d73 to your computer and use it in GitHub Desktop.
Adapters for middleware in Go
package main
// Adapter takes in a http.Handler, enhances it,
// and returns another http.Handler
type Adapter func(http.Handler) http.Handler
// Composes variadic adapters and returns a final
// adapter to be applied to the http.Handler
func Compose(adapters ...Adapter) Adapter {
return func(h http.Handler) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
}
package main
func main() {
r := mux.NewRouter()
// enhance a route handler with middleware
todosHandlerEnhancer := Compose(
WithHeader("content-type", "application/json"),
WithHeader("api-version", "v1"),
)
router.Handle("/todos", todosHandlerEnhancer(todosHandler))
// apply for the entire router
router.Handle("/", Logging(logger)(router))
}
func todosHandler(w http.ResponseWriter, r *http.Request) {
// continue normal operation
}
package main
// Add a new header with the given key, value
func WithHeader(k, v string) Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header.Add(k, v)
h.ServeHTTP(w, r)
})
}
}
// Add a new header that logs the request
func Logging(l *log.Logger) Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
l.Println(r.Method, r.URL.Path) // use your own logging solution
h.ServeHTTP(w, r)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment