Golang / GoLang Production Patterns and Web Standards Interview Questions
What is the standard Go HTTP middleware signature and how do you chain multiple middleware?
Go middleware follows a consistent adapter pattern: a function that accepts an http.Handler and returns a new http.Handler that wraps it. The signature func(http.Handler) http.Handler is the community standard — used by virtually every Go HTTP library.
// The standard middleware type
type Middleware func(http.Handler) http.Handler
// Logging middleware
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Wrap ResponseWriter to capture status code
lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(lrw, r) // call the next handler in the chain
log.Printf("%s %s %d %v",
r.Method, r.URL.Path, lrw.statusCode, time.Since(start))
})
}
type loggingResponseWriter struct {
http.ResponseWriter
statusCode int
}
func (lrw *loggingResponseWriter) WriteHeader(code int) {
lrw.statusCode = code
lrw.ResponseWriter.WriteHeader(code)
}
// Auth middleware
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return // short-circuit — next.ServeHTTP never called
}
next.ServeHTTP(w, r)
})
}
// Recovery middleware — catch panics in handlers
func recoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
log.Printf("panic recovered: %v\n%s", rec, debug.Stack())
http.Error(w, "internal server error", http.StatusInternalServerError)
}
}()
next.ServeHTTP(w, r)
})
}
// Chaining middleware — applied right-to-left (outermost runs first)
handler := recoveryMiddleware(loggingMiddleware(authMiddleware(mux)))
// Request order: recovery → logging → auth → mux → handler
// Cleaner chain helper
func Chain(h http.Handler, middlewares ...Middleware) http.Handler {
for i := len(middlewares) - 1; i >= 0; i-- {
h = middlewares[i](h)
}
return h
}
handler = Chain(mux, recoveryMiddleware, loggingMiddleware, authMiddleware)
Invest now in Acorns!!! 🚀
Join Acorns and get your $5 bonus!
Acorns is a micro-investing app that automatically invests your "spare change" from daily purchases into diversified, expert-built portfolios of ETFs. It is designed for beginners, allowing you to start investing with as little as $5. The service automates saving and investing. Disclosure: I may receive a referral bonus.
Invest now!!! Get Free equity stock (US, UK only)!
Use Robinhood app to invest in stocks. It is safe and secure. Use the Referral link to claim your free stock when you sign up!.
The Robinhood app makes it easy to trade stocks, crypto and more.
Webull! Receive free stock by signing up using the link: Webull signup.
More Related questions...
