Passing DB Connections to http Handlers

2,913 views
Skip to first unread message

Brady Sullivan

unread,
Sep 1, 2013, 4:11:48 PM9/1/13
to golan...@googlegroups.com
Hey everyone,

I've been looking into this similar topic, https://groups.google.com/forum/#!topic/golang-nuts/g_zHm1E3sIs

My question, is if I am going to be using 2 (or more) databases (MySql, MongoDB, redis, etc) is it better to put them all in a single struct and implement the http handlers as interface methods to that struct, or should I be copying the sessions for each handler?

I'm looking for a way to build a more robust web application and the Golang Web App tutorial (still very well written and informative) doesn't quite reach this depth of application.

Thoughts?

Current code: https://gist.github.com/bradysullivan/6407010

Andy Balholm

unread,
Sep 2, 2013, 12:04:36 PM9/2/13
to golan...@googlegroups.com
I use global variables myself.

Julien Schmidt

unread,
Sep 2, 2013, 12:23:51 PM9/2/13
to golan...@googlegroups.com
Exactly what I'd recommend you.
The database/sql package is designed for concurrent use. You can just use the global handler without caring about connections and synchronization.

If you need an introduction the the database/sql package, take a look here: https://github.com/VividCortex/go-database-sql-tutorial 

On Monday, September 2, 2013 6:04:36 PM UTC+2, Andy Balholm wrote:
I use global variables myself.

Brady Sullivan

unread,
Sep 3, 2013, 2:37:03 AM9/3/13
to golan...@googlegroups.com
Would it *not* make sense to make a struct that carries this information? I feel like it's cleaner and better kept together by not having a global variable for this connection.

Konstantin Khomoutov

unread,
Sep 3, 2013, 5:16:41 AM9/3/13
to Brady Sullivan, golan...@googlegroups.com
On Mon, 2 Sep 2013 23:37:03 -0700 (PDT)
Brady Sullivan <br...@bsull.com> wrote:

> > Exactly what I'd recommend you.
> > The database/sql package is designed for concurrent use. You can
> > just use the global handler without caring about connections and
> > synchronization.
> >
> Would it *not* make sense to make a struct that carries this
> information? I feel like it's cleaner and better kept together by not
> having a global variable for this connection.

I think what has been proposed to you is just a pragmatic approach: the
Go designers decided that database connections must support concurrent
usage (possibly using locking internally), and so you get it no matter
whether you like it or not, or whether you carry one connection per
"worker" ensuring it's never used concurrently or have a single one
which must serialize requests to itself.

Luke Mauldin

unread,
Sep 3, 2013, 10:35:09 AM9/3/13
to golan...@googlegroups.com
In this scenario, I use s struct to combine the fields together instead of using global variables.  Maybe that is because of my C++/Java/.NET programming where global variables were discouraged.

Gustavo Niemeyer

unread,
Sep 3, 2013, 10:57:48 AM9/3/13
to Brady Sullivan, golan...@googlegroups.com
If it's not just a quick hack, I'd recommend providing the session to
the handlers via other means than global variables.

If you're using mgo with MongoDB, I also recommend copying the session
from the initial one for each handled request, and using defer
session.Close() on it so that its resources return to the pool
afterwards. This is cheap in terms of resources, and will ensure that
requests do not stumble upon each other in terms of errors and slow
downs caused by potential long running activities. It's not about
concurrency safety, though. You can safely use a single mgo session
with as many goroutines as desired.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.



--

gustavo @ http://niemeyer.net

Brady Sullivan

unread,
Sep 3, 2013, 12:55:59 PM9/3/13
to golan...@googlegroups.com, Brady Sullivan
When you say "other means" is my struct approach reasonable?

Example code: https://gist.github.com/bradysullivan/a8a300fceed30a39cc75

Kamil Kisiel

unread,
Sep 3, 2013, 1:26:14 PM9/3/13
to golan...@googlegroups.com
I use a custom handler type for providing context in to my web handlers. The general approach is something like this:

type context struct {
    // whatever context you need to pass in to your handlers, DB connections, etc.
}

type contextHandler struct {
    c context
    f contextFunc
}

type contextFunc func(c context, w http.ResponseWriter, r *http.Request)

func (h contextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    h.f(h.c, w, r)
}

func f1(c context, w http.ResponseWriter, r *http.Request) {
    // Implement the handler here
}

func main() {
    c := NewContext(...) // Set up your context here
    http.Handle("/", contextHandler{c, f1})
}

It's partially based off of the article "Painless Web Handles in Go": http://shadynasty.biz/blog/2012/08/07/painless-web-handlers-in-go/

daniel....@gmail.com

unread,
Sep 3, 2013, 7:58:35 PM9/3/13
to golan...@googlegroups.com
At 99designs we're using a global service container to do DI ( http://godoc.org/github.com/99designs/goodies/depinject ).

The whole 'framework' is about 100 lines but it keeps our code relatively clean.
Reply all
Reply to author
Forward
0 new messages