# Notes: Go Design Patterns - Singleton Pattern

Singleton pattern makes sure that only one instance of an object is created. This pattern is used to create DB connections or connections with other external systems.
We'll see its usage by trying to create a singleton MongoDB connection:
```
func getNewMongoClient() *mongo.Client {
	if mongoClient == nil {
		once.Do(
			mongoConnect,
		)
	} else {
		fmt.Println("mongo client already created.")
	}

	return mongoClient
}
```
Here `once.Do` makes sure that this section of the code gets executed only one time no matter how many times it is called. We could have used mutex locks as well but the right way to implement a singleton pattern in Go is to use the sync package’s `Once.Do` function. This function makes sure that your specified code is executed only once and never more than once.

To run the example code, first, start a mongo server using docker: `docker run -d -p 27017:27017 --name mongo-server mongo:latest`

Now, once you run this code, you'll see that only the first `getNewMongoClient()` will return success while subsequent calls will fail.

Working code to test:

```
package main

import (
	"context"
	"fmt"
	"log"
	"sync"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var once sync.Once

var mongoClient *mongo.Client

// start mongo server by using this command:
// docker run -d -p 27017:27017 --name mongo-server mongo:latest
func mongoConnect() {
	var err error

	// Set client options
	clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

	// Connect to MongoDB
	mongoClient, err = mongo.Connect(context.TODO(), clientOptions)

	if err != nil {
		log.Fatal(err)
	}

	// Check the connection
	err = mongoClient.Ping(context.TODO(), nil)

	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("connected to mongo!")
}

func getNewMongoClient() *mongo.Client {
	if mongoClient == nil {
		once.Do(
			mongoConnect,
		)
	} else {
		fmt.Println("mongo client already created.")
	}

	return mongoClient
}

func main() {
	getNewMongoClient()
	getNewMongoClient()
	getNewMongoClient()
	getNewMongoClient()
}

```
