3 ms·
The request context is I think the most annoying part of go http handling. Oh you want to wrap your handler with something that does db.Begin()/db.Commit()? We
by bfrog 13y ago
The request context is I think the most annoying part of go http handling.
Oh you want to wrap your handler with something that does db.Begin()/db.Commit()? Well you need to stuff that tx somewhere...
so then your options are a global map[*http.Request]interface{} with mutexes or pass it as an arg. Passing it in as an arg means you either lose compile time type checking because you use reflect or lose the ability to add more middlewares that build up request context. The map[]interface{} also loses compile time type checking for the most part unless you do something per type of context, with more mutexes.
The second option is the sanest, but means either reflect if you have more than one context arg to build out (sql.Tx + cache + oauth grant + whatever else maybe?) or you have some common context object that may or may not use everything every request and your just adding more context members all the time that may or may not be initialized for that particular request.
Sometimes I miss the dynamic typing and/or compile time type templating.
- codegangsta 13y agoI find the args approach the most appealing to me. Yeah you lose some compile time safety. Like you said the other option is a global context with mutexes which still somewhat misses some compile time safety. It basically boils down to reflection over type assertions. I think Martini handles this pretty darn well if I do say so myself ;)
- mmgutz 13y agoI think you get the best of both worlds with `gocraft/web`. I feel args when you inject 3 or more (db, session ...) is cumbersome. `gocraft/web` is faster too since it has less reflection.
- codegangsta 13y agoAgreed. I really like how gocraft does contexts. Very cool way to structure your app
- acrispino 13y agoYou can use closures: func SomeHandler(foo Foo) { return func(w http.ResponseWriter, req *http.Request) { // use foo } } // later, during init http.HandleFunc("/foo", SomeHandler(someFoo)) or method values, introduced in go 1.1: type handler struct { foo Foo } func (h *handler) bar(w http.ResponseWriter, req *http.Request) { // use h.foo } func (h *handler) qux(w http.ResponseWriter, req *http.Request) { // use h.foo } // later h := handler{ foo: someFoo, } http.HandleFunc("/bar", h.bar) http.HandleFunc("/qux", h.qux)
- BarkMore 13y agoThe GP's comment is about request context, not handler context.