Is it possible to combine http.ServeMux?

Hello

Is it possible to combine many http.ServeMux together? For example I want to have an inner mux that serves “/users” and then I want to have that inner mux served on “/api” by an outer mux without changing the routes of the inner mux.

Thanks

You should have a look at the source for DefaultServeMux - it is quite simple at its heart, and there is no harm in writing your own router if you accept the standard signature for HandlerFuncs. You could then easily support this (or any other feature) you want.

It is not supported out of the box with the default router so to do it with that you’d need to write a handler which called other handlers. You could also look at other go routers as some of them do support this -

Gorilla supports this for example.

Could you please provide an example of that using the standard library? Thanks!

Sure you can. The ServeMux is an http.Handler.

package main

import (
	"fmt"
	"net/http"
)

func main() {
	apiMux := http.NewServeMux()
	apiMux.HandleFunc("/test", handleAPITest)

	usersMux := http.NewServeMux()
	usersMux.HandleFunc("/test", handleUsersTest)

	topMux := http.NewServeMux()
	topMux.Handle("/api/", http.StripPrefix("/api", apiMux))
	topMux.Handle("/users/", http.StripPrefix("/users", usersMux))

	http.ListenAndServe(":1234", topMux)
}

func handleAPITest(w http.ResponseWriter, req *http.Request) {
	// Called for /api/test
	fmt.Fprintf(w, "Hello from /api/test\n")
}

func handleUsersTest(w http.ResponseWriter, req *http.Request) {
	// Called for /users/test
	fmt.Fprintf(w, "Hello from /users/test\n")
}

Note the http.StripPrefix so that the two second level muxes don’t need to know where they’re “rooted”.


Edit: I noticed I didn’t implement exactly what you asked, but I think you can see the method of combining muxes with prefixes at least. :slight_smile:

3 Likes

This is amazing! Thank you so much!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.