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 .

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 blog post is 100% human-written, and has nothing derived from LLMs (be it code, editorial support or prose).

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.