HTTP wrappers using Decorator pattern

Hello good people!

I read this post from Mat Ryer:

And he makes use of this adapter:

func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
  for _, adapter := range adapters {
    h = adapter(h)
  return h

Each handler that is passed to the Adapt function has an h.ServeHTTP(w, r) like this one:

func Notify() Adapter {
  return func(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
      defer log.Println("after")
      h.ServeHTTP(w, r)  

For what I understand, in each iteration the h will be overwritten by the next adapter, am I correct? And why the h.ServeHTTP(w, r) is not executed in each iteration in case there are multiple handlers like this? Is it chaining? If so, why?

http.Handle("/", Adapt(indexHandler, AddHeader("Server", "Mine"),
1 Like

Each time the h gets over-written it wraps the previous middleware/Adaptor hence when its ServeHTTP is called for that Adaptor, all previous ones are called like as if unwinding a coil. This allows you to have an interesting step where you can stop running down the coil if the response has been delivered.

1 Like

Thanks a lot for your answer.

You said all previous ones are called like as if unwinding a coil, it sounds like the indexHandler will be called 4 times? One for each handler?

No, IndexHandler will be wrapped by the first adapter to produce a new handler. That new handler will be wrapped by the next adapter and so on producing a chain.
The order of execution of the example you provided would be:
Notify(logger), CopyMgoSession(db), CheckAuth(providers), AddHeader(“Server”, “Mine”) and finally indexHandler.

1 Like

Thank you @netixen and @influx6, both answers are clarifying!

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