Writing middleware in #golang and how Go makes it so much fun.

Good middleware shouldn’t deviate at all from the standard library —the http.Handler type is sacred.

Adapter type

type Adapter func(http.Handler) http.Handler
func Notify() Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("before")
defer log.Println("after")
h.ServeHTTP(w, r)
}
}
}
func Notify(logger *log.Logger) Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger.Println("before")
defer logger.Println("after")
h.ServeHTTP(w, r)
}
}
}

Using the Adapters

logger := log.New(os.Stdout, "server: ", log.Lshortfile)
http.Handle("/", Notify(logger)(indexHandler))
func Adapt(h http.Handler, adapters ...Adapter) http.Handler
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
http.Handle("/", Adapt(indexHandler, AddHeader("Server", "Mine"),
CheckAuth(providers),
CopyMgoSession(db),
Notify(logger),
)
  • Notify (log “before” string — maybe with some other bits)
  • CopyMgoSession (copy db session and make it available to handler)
  • CheckAuth (check auth cresds and bail if failed)
  • AddHeader (add response header)
  • indexHandler
  • Any AddHeader deferred functions
  • Any CheckAuth deferred functions
  • CopyMgoSession deferred function (probably closing the database copy)
  • Notify deferred function (writing “after” string)

Questions?

  • EDIT: Code tweaks for readability.
  • EDIT 31 Aug: The Adapt execution was reversed in my example.

--

--

--

Founder at MachineBox.io — Gopher, developer, speaker, author — BitBar app https://getbitbar.com — Author of Go Programming Blueprints

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mat Ryer

Mat Ryer

Founder at MachineBox.io — Gopher, developer, speaker, author — BitBar app https://getbitbar.com — Author of Go Programming Blueprints

More from Medium

Publish a Go module in a monorepo

Using open source packages — Golang

Build simple gRPC server with Golang

#GoroutineScoopTrap