« Back to home

Handlerfunc vs Handlefunc in Go

Posted on

In getting used to web development in Go, the single thing that confused me most was the difference between Handler, HandleFunc and HandlerFunc. After looking at the source code I finally understood it, so here’s an attempt to make it clear.

Go’s Handler is an interface consisting of a single method:

ServeHTTP(w ResponseWriter, r *Request)

Because it’s annoying to have to create an object just so you can give it a single method ServeHTTP, Go has a second type called HandlerFunc.

type HandlerFunc func(ResponseWriter, *Request)

Go then defines a generic ServeHTTP method with that function type as receiver:

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

This works because in Go, functions can have methods just like objects.

These 4 lines of code (the type definition and the method definition) basically say that any function which matches the signature func(ResponseWriter, Request) will have the ServeHTTP method necessary to be used as a Handler, if you cast it to be of type http.HandlerFunc.

So

http.HandlerFunc( func (w http.ResponseWriter, r *http.Request) { 
  // Your code here
})

isn’t calling a function called HandlerFunc; rather, it’s type casting the defined function to be of type HandlerFunc. At that point it automatically gets the ServeHTTP method defined in stdlib. That, in turn, is all it needs to be treated as a Handler.

So the ‘trick’ is that a HandlerFunc is a Handler, but defined using a func. If you write an appropriate function and cast it to be a HandlerFunc, it too becomes a Handler.

Unfortunately http.HandlerFunc is also easily confused with http.HandleFunc. Whereas a HandlerFunc is a Func that’s a Handler, HandleFunc is the function which tells Go to call a Func in order to Handle a request.

The way to remember this is that the verb is “Handle”, but the noun is “Handler”, and method names are generally verbs. Hence to handle a request you call HandleFunc with appropriate arguments; whereas a HandlerFunc is a noun for a handler defined using a func.