Search code examples
mongodbdockergoconnection

panic: error parsing uri: scheme must be "mongodb" or "mongodb+srv" Golang - MongoDB connection error


This is the error I am getting when I docker-compose up my app in docker-desktop.

{ { }}
panic: error parsing uri: scheme must be "mongodb" or "mongodb+srv"
goroutine 1 [running]:
go-products/database.ConnectDB(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/app/database/database.go:15 +0x145
main.main()
/app/main.go:14 +0x13d

Here is my main.go file

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "go-products/config"
    "go-products/database"
    "net/http"
)

func main() {
    conf := config.GetConfig()
    fmt.Println(conf)
    db := database.ConnectDB(conf.Mongo)
    fmt.Println(db)
    r := mux.NewRouter()
    http.ListenAndServe(":8080", r)
}

This is the database file where I try to make connection.

package database

import (
    "context"
    "go-products/config"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func ConnectDB(conf config.MongoConfiguration) *mongo.Database {
    connection := options.Client().ApplyURI(conf.Server)
    client, err := mongo.Connect(context.TODO(), connection)

    if err != nil {
        panic(err)
    }

    return client.Database(conf.Database)
}

config.go file

package config

import "github.com/spf13/viper"

type Configuration struct {
    Environment string
    Mongo       MongoConfiguration
}

type MongoConfiguration struct {
    Server string
    Database string
    Collection string
}

func GetConfig() Configuration {
    conf := Configuration{}
    viper.SetConfigName("config")
    viper.SetConfigType("yml")
    viper.AddConfigPath("./config")

    err := viper.ReadInConfig()
    if err != nil {
        panic(err)
    }

    return conf
}

this is config.yaml file.

environment: dev
mongo:
  server: mongodb://mongo:27017
  database: Mgo
  collection: Products

I have checked the official documentation and some resources but couldn't find a way to handle this in Golang environment. What should I change here?


Solution

  • In your GetConfig() function, you declare a variable of type Configuration, and you return it, but you never actually assign anything to any of its fields. That's why your fmt.Println() call to dump out the configuration just shows { { }}; none of the fields have assigned values.

    You need to unmarshal the Viper configuration into the config structure:

    func GetConfig() (Configuration, error) {
        var conf Configuration
        // ... viper setup ...
    
        err := viper.ReadInConfig()
        if err != nil {
            return Configuration{}, err
        }
    
        // *** unmarshal the Viper config into the Configuration struct ***
        err = viper.Unmarshal(&conf)
        if err != nil {
            return Configuration{}, err
        }
        // ***
    
        return conf, nil
    }