What is ServeMux in Go?
ServeMux is a request router that decides which function should handle an incoming request, it matches the URL of an incoming http request to a set of registered patterns which we define like so:
mux:= http.NewServeMux()
mux.HandleFunc("/", home)
mux.HandleFunc("/add",addNum)
when a user hits / url then the home function is run, similarly when a user hits the "/add" url the addNum function will be run.
Simple right?
But there's a catch, go's servemux supports two kinds of URL patterns:
Fixed Paths
Subtree Paths
Fixed Paths- These URL patterns do not have a trailing slash(a slash at end) like "/add" in the above example.
Subtree Paths- These URL patterns end with a trailing slash like "/add/" or simply "/" as in the above example.
What happens is that fixed path patterns are only matched when the URL path exactly matches the pattern we define like "/add", so if we go to the URL "/add/" the addNum function won't run because in the
mux.HandleFunc ("/add",addNum) function,
we are specifying that only run the addNum function if the URL matches exactly to "/add".
In contrast, the "/" is a subtree path (because it ends with a slash /) so if we go to any URL starting with the / (other than the "/add"), the home function will run as we defined mux.HandleFunc ("/", home), so any URL path starting with / will run the function home.
Another example of a subtree path would be "/multiply/", and let's say its defined as:
mux.HandleFunc("/multiply/",mulNum)
so if a user goes to the URL "/multiply/abcd", the servemux automatically redirects to "/multiply/" and runs the mulNum function, and even if the user goes to "/multiply" (no trailing slash), the ServeMux automatically adds a trailing slash and runs the mulNum function.
Longer URL wins
In go's ServeMux, the longer URL always takes precedence over the shorter ones, no matter the order in which the routes are defined in the code,
for example:
mux.HandleFunc("/",home)
mux.HandleFunc("/message",viewMessage)
mux.HandleFunc("/message/create",createMessage)
suppose a user goes to "/message/create", what happens is:
the "/" pattern matches β
the "/message" pattern also matchesβ
the "/message/create" pattern also matches β
but the pattern which is longest will be selected and its corresponding function will be run, i.e. in this case: createMessage function will be run.
So this gives a really cool side effect- we can register routes in any order and go's ServeMux will always match the URL with the longest matching pattern:
(you can register the routes in any order ):
mux.HandleFunc("/message",viewMessage)
mux.HandleFunc("/",home)
mux.HandleFunc("/message/create",createMessage)
While this might seem like a small thing but if you are coming from nodejs and express, you know the pain, route order matters there and getting it wrong can cause bugs. Go's ServeMux just handles it automatically.
Top comments (0)