Search code examples
gomiddlewarego-alice

Middleware using Alice and HttpRouter


I can't seem to work out how to use middleware and Http Router properly together.

My code is:

type appContext struct {
  db *mgo.Database
}

func main(){
  c := appContext{session.DB("db-name")}
  commonHandlers := alice.New(context.ClearHandler, basicAuthHandler)

  router := NewRouter()
  router.Post("/", commonHandlers.ThenFunc(c.final))

  http.ListenAndServe(":5000", router)
}

The final middleware is:

func (c *appContext) final(w http.ResponseWriter, r *http.Request) {
  log.Println("Executing finalHandler")
  w.Write([]byte("TESTING"))
}

but I want my basicAuthHandler to be part of the commonHandlers. It also needs the context so that I can query the db.

I have tried this:

func (c *appContext) basicAuthHandler(w http.ResponseWriter, r *http.Request) {
  var app App
  err := c.db.C("apps").Find(bson.M{"id":"abcde"}).One(&app)
  if err != nil {
    panic(err)
  }

  //do something with the app
}

but I get the error undefined: basicAuthHandler. I understand why I'm getting the error but I don't know how to avoid it. How can I provide the context to the basicAuthHandler and still use it in the commonHandlers list for Alice?


Solution

  • Your middleware needs to have the signature

    func(http.Handler) http.Handler
    

    This way your middleware is wrapping handlers, not just providing a final handler. You need to accept an http.Handler, do whatever processing needs to be done, and call ServeHTTP on the next handler in the chain. Your basicAuthHandler example could look like this:

    func (c *appContext) basicAuthHandler(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            var app App
            err := c.db.C("apps").Find(bson.M{"id": "abcde"}).One(&app)
            if err != nil {
                panic(err)
            }
            h.ServeHTTP(w, r)
    
        })
    }
    

    (though you don't want to panic in your app, and should provide a better error response)