When routing in go, we attach a normal function to a router and call it a handler, for example :
package main
func home(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello from Snippetbox"))
}
func main(){
mux := http.NewServeMux()
mux.HandleFunc("/", home)
}
Most of would just call that home is a handler without knowing how its orginally not a handler and is transformer into one.
To understand this, first we need to understand what is a handler?
A Handler is any object that has the ServeHTTP() method, but why? Let's see in the source code of go, inside the net/http package, in server.go we will see this:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
which means, to be a Handler, that thing should contain the ServeHTTP() method with the exact signature as above.
But now the question arises, so why does my routes work?
Here's the answer :
it works because when we register the route like this:
mux.HandleFunc("/", home)
HandleFunc() secretly wraps the home function inside http.HandlerFunc() which in turn attaches the ServeHTTP() method to the home function and makes it indirectly a "Handler"
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r) // just calls the home function
}
So to wrap this is the total flow:
You might also get it that we can directly call the HandlerFunc() instead of HandleFunc(), yes we can but HandleFunc() is easer to write and does the same work internally.
This is how we can directly call the HandlerFunc() :
mux := http.NewServeMux()
mux.Handle("/", http.HandlerFunc(home))
Furthermore, ServeMux itself is also a Handler, it has its own ServeHTTP() method, look at the source code :
Notice(line 2847), the *ServeMux in the receiver part of the function,that means ServerHTTP() belongs to ServeMux, making it a Handler too anddd that's why we can pass it directly to http.ListenAndServe()
notice, the second parameter of the ListenAndServe() function is a handler so the mux we pass in there to run our server is also a handler
err := http.ListenAndServe(":4000", mux)//mux is a handler!
Next time you write mux.HandleFunc("/",home) - you'll know that home alone isn't really a handler, but http.HandlerFunc(home) is and that's exactly what Go creates behind the scenes:)
Thanks for reading till here, see you in the next post ;)




Top comments (0)