[Go] Understanding net/http package - Handle(r) family
Tags: go, webdev, beginners
Published: 2024-02-20 13:50:46

*image credit to [Renee French](https://reneefrench.blogspot.com/), the [source is the one of the official Go blog posts](https://go.dev/blog/gopher)

# TL; DR

- "Handler"s are types, whereas "Handle"s are functions that register them.
- `HandlerFunc` can be understood as a "wrapper" that equips a plain function with the interface `Handler`.
- All you need to understand is the type `Handler`; everything else follows from it.

# Introduction: A family of confusing naming - Handle(r) family

As a newbie who recently having started digging into Go, I find it fascinating in that I can basically live without relying on third party packages. And one of the best things I think you can do with only using the standard packages, is to run a server using [net/http](https://pkg.go.dev/net/http). 

However, once I began looking into tutorials and other learning materials(like [gowebexamples.com](https://gowebexamples.com/)) for using this package, the family of “Handle(r)” was a little bit confusing to understand in its naming. I believe I am not the only one:

- Handler and HandlerFunc
- Handle and HandleFunc

So in this short article, I would like to explain how I understand their differences and my own tip to distinguish them in a simple way.

## Distinguishing the family members from naming

Let’s talk about `Handler` and `Handle` first. If you read the documentation of the [net/http](https://pkg.go.dev/net/http) package, `Handler` is an interface that implements `ServeHTTP` function, whereas `Handle` is either a function or a method belonging to the type `*ServeMux`. Namely, `Handle` function/method registers a given `Handler` to its tied `(Default)ServeMux`. 

You can find almost the identical relationship between `HandlerFunc` and `HandleFunc`. So here is my first personal tip to understand the “Handle(r)” family:

*1)"Handler"s are types, whereas "Handle"s are functions that register them.*

But understanding the difference between `Handler` and `HandlerFunc` is not that simple. See this explanation of `HandlerFunc` in the documentation:

> The HandlerFunc type is an adapter to allow the use of ordinary functions as HTTP handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f.

So `HandleFunc` is an "adapter". The term "adapter" would be probably from the [adapter design pattern](https://en.wikipedia.org/wiki/Adapter_pattern), which simply means that an adapter changes the interface without touching the internal logic of the adapted target. Thus, the explanation here can be understood as 

*2)`HandlerFunc` can be understood as a "wrapper" that equips a plain function with the interface `Handler`.*

and this second tip becomes more obvious once we read [this line from the source code of the package](https://cs.opensource.google/go/go/+/master:src/net/http/server.go;l=2165):

```go
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}
```

So when we convert a function of type `func(w http.ResponseWriter, r *http.Request)` into a `HandlerFunc`, we must have in mind that the function will behave exactly the same as `ServeHTTP(w, r)`. 

## The type `Handler` is at the heart of the family

Now from the tips 1) and 2), we can infer the following takeaway which I would like to emphasize as a separate tip:

*3)All you need to understand is the type `Handler`; everything else follows from it.*

But what does it mean by "understanding `Handler`"? Although the low-level implementation can be found(for example, the method [`Serve`](https://cs.opensource.google/go/go/+/go1.22.0:src/net/http/server.go;l=3225)), I would like to mention that it is an interface with only one method. Since we only have to implement one single method `ServeHTTP`, we can construct a handler with more stateful layers.

For example:

```go
type WrappedHandler struct {
  // some internal variables representing states
}

func (wh *WrappedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  // …
}

type WrapperHandler struct {
  // additional variables 

  wrapped *WrappedHandler
}

func (wh *WrapperHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  // do some layered logics

  // run the wrapped handler’s logic
  wh.wrapped.ServeHTTP(w, r)
}
```

Moreover, using `HandlerFunc`, we can make a middleware in a simple way following this pattern(I learned it from the book [Learning Go, 2nd ed. by Jon Bodner](https://www.amazon.com/Learning-Go-Idiomatic-Real-World-Programming/dp/1492077216)).

```go
func middleware(handler http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    // do some middleware stuffs

    // call the original handler’s ServeHTTP
    handler.ServeHTTP(w, r)
  })
}

```

# Conclusion
The three tips mentioned here are totally personal. However, I find it fairly useful whenever I get confused with reading the names of the members of “Handle(r)” family, clearly distinguishing what each type/function does. Moreover, from understanding the roles of them, I can be more familiar with the structure of how net/http package works under the hood.