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 https://blog.questionable.services/article/custom-handlers-avoiding-globals/. 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

1 Like