🍣

【Go】複数のミドルウェアを扱う際の効率的なルーティング方法

2023/04/11に公開

middlewareが複数ある時のルーティング

middlewareを複数書くとき、そのまま書こうと思うと以下のような記述になるかと思います。

mux.HandleFunc("/about", middleware1(middleware2(middleware3(aboutHandler))))

複数のミドルウェア関数を連鎖的に適用する方法ですが、長くなりがちで、可読性が低下する場合があります。特に、多数のミドルウェアを組み合わせた場合は、可読性が悪化し、ネストが深くなり、コードの理解が困難になることがあります。

スライスを使って簡潔に表現する

そこで、以下のようにミドルウェア関数を []func(http.Handler) http.Handler 型のスライスとして定義し、applyMiddleware という関数で適用してみます。この方法では、ミドルウェアを簡潔に表現でき、読みやすいコードを実現できます。

func applyMiddleware(h http.Handler, mws ...func(http.Handler) http.Handler) http.Handler {
	for i := len(mws) - 1; i >= 0; i-- {
		h = mws[i](h)
	}
	return h
}

func main() {
	mux := http.NewServeMux()

	// ミドルウェア関数をスライスとして定義する
	middlewares := []func(http.Handler) http.Handler{
		middleware1,
		middleware2,
		middleware3,
	}

	// ミドルウェア関数を適用する
	mux.HandleFunc("/about", applyMiddleware(aboutHandler, middlewares...))
}

この方法では、applyMiddleware 関数が、引数として渡された http.Handler に対して、スライス内のミドルウェア関数を逆順に適用して、適用後の http.Handler を返します。mux.HandleFunc の引数としては、適用後の http.Handler として aboutHandler を渡します。

この方法を取れば、可読性が高く、ネストが深くならないため、ミドルウェア関数の追加や削除などの変更にも柔軟に対応できますね!

Discussion