Let's assume I have a very simple repository interface that only reads from target database:
type UserRepository interface {
read(ctx context.Context, id WHAT_TYPE_I_SHOULD_USE_HERE) models.User
}
NOTE: note that in id parameter I do not have any idea what to user as id type as id in MongoDB
is ObjectId
and in schema based DBs it might be a UUID
field. My primary database is MongoDB if it helps, but I might switch to schema-based DBs.
Now I have a MongoDBRepository
struct that has read()
attached to it:
type MongoDBRepository struct {
}
func (mo MongoDBRepository) read(ctx context.Context, id primitive.ObjectID) {
fmt.Printf("read user %s from MongoDB", id)
}
I have a method that connects to MongoDB:
func ConnectMongoDB() (*mongo.Client, context.CancelFunc) {
client, err := mongo.NewClient(options.Client().ApplyURI(configs.MongoURI()))
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
err = client.Connect(ctx)
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
log.Print("Successfully connected to MongoDB!")
return client, cancel
}
Now as interface is implemented we can have a similar repository for MySQL
/PostgreSQL
and also ConnectMySQL
/ConnectPostgreSQL
.
The issue I have is in my main function how should I handle connecting to my current database repository and how to use it in my controllers to read or update a document/record?
When I pass my connection to a controller method its type is set to *mongo.Client
how can I abstract it away so my controller method that gets DB connection is not bound to target DB type?