Connect to Mongo Atlas with Go
· 327 wordsWith the recent closure of mLab and the simple migration tool across to their successor, Mongo Atlas, I’ve recently been tasked with moving a web service across to Atlas. The data was simple to move (thanks to the migration tool), but we had to change the code to handle this new connection. The service is written in Go (as in golang) and I wanted to give an example of how to connect to Atlas - as it was a little different from connecting to mLab.
In our example below, we’re using the mgo driver, so it will be a little different to using the official Mongo driver. The key changes in the code when using Atlas over mlab include:
- Requiring a TLS connection
- Having multiple hosts (due to shards)
- A different auth database (admin vs. the owner’s db)
package main
import (
"crypto/tls"
"errors"
"fmt"
"log"
"net"
"net/url"
"strings"
"time"
"github.com/globalsign/mgo"
)
var mongoSession *mgo.Session
func main() {
var err error
mongoSession, err = makeMongoSession()
if err != nil {
log.Fatal(err)
}
// Try connection
if err := mongoSession.Ping(); err != nil {
log.Fatal(err)
} else {
fmt.Println("Connection Established to Mongo")
}
}
func makeMongoSession() (*mgo.Session, error) {
// Our connection string - would be an environment variable most likely
// Note: we changed the host to the first shard
mongoURI := "mongodb+srv://mongouser:mongopass@cluster-shard-00-00.mfv6x.mongodb.net:27017/dbname"
parts, err := url.Parse(mongoURI)
if err != nil {
return nil, err
}
password, isSet := parts.User.Password()
if !isSet {
return nil, errors.New("Error parsing Mongo password (env var)")
}
// Build our list of hosts (currently set to 3)
mongoHost := []string{
parts.Host,
strings.ReplaceAll(parts.Host, "00-00", "00-01"),
strings.ReplaceAll(parts.Host, "00-00", "00-02"),
}
dialInfo := mgo.DialInfo{
Addrs: mongoHost,
Timeout: 15 * time.Second,
Database: strings.ReplaceAll(parts.Path, "/", ""),
Username: parts.User.Username(),
Password: password,
Source: "admin", // auth db
}
// Connect with TLS
tlsConfig := &tls.Config{}
dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
conn, err := tls.Dial("tcp", addr.String(), tlsConfig) // add TLS config
return conn, err
}
return mgo.DialWithInfo(&dialInfo)
}
∞