Best way to refactor connection overhead from my handler functions?

I am using the official mongo driver for golang.

I am working on an HTTP server. And all of my handler function has the same pattern. All handlers are in handler/handler.go.

client, _ := mongo.NewClient(options.Client().ApplyURI("mongodb://127.0.0.1:27017"))
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
err := client.Connect(ctx)
if err != nil {
    panic(err)
}

defer client.Disconnect(ctx)
collection := client.Database("foo").Collection("bar")

What other ways are available than extracting this block to a function and calling in all the handlers?

Can I make a connection in the main.go file and use it in all the handlers? How can I do that? I am using gorilla mux by the way.

Anything you’d like to suggest?

Hi @sntshk,

A couple of things you can look into:

  1. Per our documentation, the mongo.Client type is safe for concurrent use, so if you’re always connecting to the same MongoDB instance, you can create a single Client and re-use it between handlers rather than creating a new one in each handler. Note that this does come with some overhead, as a Client keeps a connection pool per node in your MongoDB cluster, so if you perform a lot of concurrent database operations, you could potentially keep around a large connection pool.

  2. Go allows you to pass a function on a struct as a callback, so you can probably create a struct to store application state and helper functions. That struct could have separate functions for each of your HTTP requests and each handler function should have the signature func(http.ResponseWriter,*http.Request) so it can be used with HandleFunc in gorilla/mux.

  3. To go even further into suggestion (2), you could maybe set things up so your struct has a single top-level handler to do common operations like validate the request and then have that call a struct function to handle a specific request type once it’s been validated.

There’s some examples for creating stateful handlers at Custom Handlers and Avoiding Globals in Go Web Applications · questionable services. Specifically, the appContext type discussed there seems similar to what you want. I’d also recommend asking this as a more general question (e.g. “how to create stateful HTTP handlers”) on the Go mailing list or Slack workspace to get advice from others as well.

– Divjot

2 Likes

Hi Divjot,
I’m using the first method you said (a global Mongo client) but I got the connections going higher Even if I set a maximum to the pool it goes beyond it and I think this because the connections don’t get returned to the pool and I can’t find a way to close or return to the pool the connection used by functions.

i have wrote a topic with more info if you can help me.
thanks in advance