Хотя я понял общую идею, у меня возникли проблемы с поиском наилучшей практики для управления конфигурационными envs и управления подключением к БД.
Значение:
Если У меня есть хранилище (например, для PostgreSQL). Должен ли я передать функции NewRepository конфигурацию БД? Не скажется ли это как-то отрицательно на принципах архитектуры (поддержка, тестируемость и т. Д. c.)?
Как мы можем обрабатывать такие вещи, как defer db.Close ()?
Я имею в виду, что мы, очевидно, хотели бы, чтобы это было отложено по отношению к основной функции scope, поэтому проблематично c переместить этот код в «класс» репозитория (если нет способа сделать это с помощью Context?)
С другой стороны, вызов NewRepository в основной области видимости, но затем, когда db обрабатывает соединение вне ее, выглядит немного странно.
В большинстве примеров, которые я нашел, используется функция main, так что это было легко. Вопрос в том, как вы это правильно делаете, когда используете DDD (чистую / шестиугольную) архитектуру? особенно для того, чтобы все части были «подключаемыми» без изменения кода «вокруг него».
Вот пример, который я собрал, есть ли нарушение некоторых принципов образец ddd здесь? или это на самом деле, как все это делается?
1. Разве я не должен обрабатывать defer db.Close () внутри самого репозитория? может быть, с помощью контекста я могу отложить его в отношении основной области функций, но внутри самого репозитория?
2. Должен ли я действительно передать конфиг в NewRepository?
pkg / main. go:
func main() {
// get configuration stucts via .env file
configuration, err := config.NewConfig()
if err != nil {
panic(err)
}
postgresRepo, err := postgres.NewRepository(configuration.Database)
defer postgresRepo.DB.Close()
myService := autocomplete.NewService(postgresRepo)
handler := rest.NewHandler(myService)
...
...
...
}
pkg / config / config . go:
// Config is a struct that contains configuration variables
type Config struct {
Environment string
Port string
Database *Database
}
// Database is a struct that contains DB's configuration variables
type Database struct {
Host string
Port string
User string
DB string
Password string
}
// NewConfig creates a new Config struct
func NewConfig() (*Config, error) {
env.CheckDotEnv()
port := env.MustGet("PORT")
// set default PORT if missing
if port == "" {
port = "3000"
}
return &Config{
Environment: env.MustGet("ENV"),
Port: port,
Database: &Database{
Host: env.MustGet("DATABASE_HOST"),
Port: env.MustGet("DATABASE_PORT"),
User: env.MustGet("DATABASE_USER"),
DB: env.MustGet("DATABASE_DB"),
Password: env.MustGet("DATABASE_PASSWORD"),
},
}, nil
}