I am currently starting out with MongoDB on GoLang. My current use case is this.
I wish to initialize connection to my MongoDB Database in a particular package and use the returned client across several other local packages. Here is what I have tried,
I have initialized the connection to MongoDB inside a package called dataLayer as below
package dataLayer
import (
"context"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func InitDataLayer() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(credentials.MONGO_DB_ATLAS_URI))
if err != nil {
log.Fatal(err)
} else {
log.Println("Connected to Database")
}
}
Now if I wish to use the returned client in other packages, is it production safe to keep on calling initDataLayer over and over again to get back a client?
Thanks alot.
You don't have to call InitDataLayer over and over again. You need to create only one client, you can use the same client to connect to Mongo DB from various places.
Mongo client internally maintains a pool of connections, so you don't have to create this client again and again.
It's a good design to store this client as the struct field and keep reusing the same.
Edit:
Create Connection
package dataLayer
import (
"context"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
func InitDataLayer()(*mongo.Client) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(credentials.MONGO_DB_ATLAS_URI))
if err != nil {
log.Fatal(err)
} else {
log.Println("Connected to Database")
}
return client
}
main.go,
Close connection at the end of usage, otherwise connection would be leaked.
func main(){
//...
client = dataLayer.InitDataLayer()
defer client.Disconnect(context.Background())
...
}
Repository/DAL, store client in Repository struct
Interface
type BookRepository interface {
FindById( ctx context.Context, id int) (*Book, error)
}
Repository Implementation that store client in struct
type bookRepository struct {
client *mongo.Client
}
func (r *bookRepository) FindById( ctx context.Context, id int) (*Book, error) {
var book Book
err := r.client.DefaultDatabase().Collection("books").FindOne(ctx, bson.M{"_id": id }).Decode(&book)
if err == mongo.ErrNoDocuments {
return nil, nil
}
if err != nil {
return nil, err
}
return &book, nil
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With