Creating global middleware for net/http servers in Go

Featured image for sharing metadata for article

When you're writing pure net/http HTTP services with Go, you may want to wrap them in a middleware, for instance to ensure that authentication is provided, or to provide logging.

Having largely just used gorilla/mux, I found it was a little bit awkward to do so, but with thanks to Gregor Best for the help with this on the Gopher Slack, we got to the following solution.

package main

import (
	"log"
	"net/http"
)

func use(r *http.ServeMux, middlewares ...func(next http.Handler) http.Handler) http.Handler {
	var s http.Handler
	s = r

	for _, mw := range middlewares {
		s = mw(s)
	}

	return s
}

func loggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("Before %s", r.URL.String())
		next.ServeHTTP(w, r)
		log.Printf("Before %s", r.URL.String())
	})
}

func acceptHeaderMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("Accept: %v", r.Header.Get("Accept"))
		next.ServeHTTP(w, r)
	})
}

func path1(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("OK"))
}

func path2(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("also-ok"))
}

func main() {
	r := http.NewServeMux()
	r.HandleFunc("/path1", path1)
	r.HandleFunc("/path2", path2)

	wrapped := use(r, loggingMiddleware, acceptHeaderMiddleware)

	log.Fatal(http.ListenAndServe(":3000", wrapped))
}

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #go.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.