2

In my AuthMw middleware, I want to make database calls.

My database variable is initialized in main, how can I pass this to my middleware AuthMw?

func main() {
    db, err := gorm.Open("postgres", ... )
    r := mux.NewRouter()
    r.Handle("/ws", serveWebsocket(hub))
    r.Use(AuthMw)

    //
    //
    ...

} // main


func AuthMw(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.URL.Query().Get("token")
        fmt.Printf("AuthMiddleware token is: %v\n", token)

        ctx := ....

        next.ServeHTTP(w, r.WithContext(ctx))
    })
}
ain
  • 22,394
  • 3
  • 54
  • 74
Blankman
  • 259,732
  • 324
  • 769
  • 1,199
  • Have the `db` variable as global, so it can be accessed outside main. Might want to look into this : https://stackoverflow.com/questions/26211954/how-do-i-pass-arguments-to-my-handler – Shiva Kishore Mar 21 '18 at 06:29

1 Answers1

8

You have two straight-forward options that doesn't involve global variables.

Using a closure

You could re-write AuthMw into:

func AuthMw(db *DbType) (func (next http.Handler) http.Handler) {
    return func (next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // Your code goes here, now with a pointer to db
        })
    }
}

That way, you make a "factory function" that returns a new http.Handler decorator, where your db variable is accessible throught the closure.

All you need to do after this is to replace r.Use(AuthMw) with r.Use(AuthMw(db)).

This is maybe a little heavy on nested methods, so I'll instead suggest...

Using a struct

Turn AuthMw into a struct with you decorator attached as a method:

type AuthMw struct {
  db *DbType
}

func NewAuthMw(db *DbType) AuthMw {
  return AuthMw{db}
}

func (a *AuthMw) Decorator(next http.Handler) http.Handler {
    // Your code, now with a pointer to db, goes here
}

Then you just need replace r.Use(AuthMw) with r.Use(authMwVariable.Decorator).

Undreren
  • 2,811
  • 1
  • 22
  • 34