Prosta odpowiedź: przekazanie zainicjowanej puli połączeń do swoich globalnych pakietów.
np.
// package stuff
var DB *sql.DB
func GetAllStuff() (*Stuff, error) {
err := DB.Query("...")
// etc.
}
// package things
var DB *sql.DB
func GetAllThings() (*Thing, error) {
err := DB.Query("...")
// etc.
}
// package main
func main() {
db, err := sql.Open("...")
if err != nil {
log.Fatal(err)
}
stuff.DB = db
things.DB = db
// etc.
}
Definiujemy globalnych pakiet poziomie, upewnij się one eksportowane (kapitalizowane), a następnie przekazać wskaźnik do naszej puli połączeń do nich.
To jest "w porządku", ale może maskować "gdzie" rzeczy są używane. Jeśli patrzysz na handler'a, może nie być jasne, , z którego pochodzi, zwłaszcza w miarę wzrostu paczki. Bardziej skalowalne podejście może wyglądać jak poniżej:
// package stuff
type DB struct {
*sql.DB
}
func New(db *sql.DB) (*DB, error) {
// Configure any package-level settings
return &DB{db}, nil
}
func (db *DB) GetAllStuff() (*Stuff, error) {
err := db.Query("...")
// etc.
}
// package things
type DB struct {
*sql.DB
}
func New(db *sql.DB) (*DB, error) {
// Configure any package-level settings
return &DB{db}, nil
}
func (db *DB) GetAllThings() (*Thing, error) {
err := db.Query("...")
// etc.
}
// package main
func main() {
db, err := sql.Open("...")
if err != nil {
log.Fatal(err)
}
stuffDB, err := stuff.New(db)
if err != nil {
log.Fatal(err)
}
thingsDB, err := things.New(db)
if err != nil {
log.Fatal(err)
}
// Simplified.
http.HandleFunc("/stuff/all", stuff.ShowStuffHandler(stuffDB))
http.HandleFunc("/things/all", things.ShowThingsHandler(thingsDB))
// etc.
}
func ShowStuffHandler(db *stuff.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// We can use our stuff.DB here
stuff, err := db.GetAllStuff()
// etc.
}
}
Jeśli masz więcej niż tylko połączenia DB jako zależność (np config params, hostów, etc.), owinąć je w things.Env
struct lub stuff.Env
struct dla każdej paczki.
Przykładem może być funkcja things.New("deps...") *Env
, która zwraca skonfigurowany *things.Env
, który zawiera zależności używane przez pakiet things
.
Przez "pakietów" masz na myśli różnych projektów/bibliotek? – ZAky
Nie, tylko pakiety wewnętrzne. – user1952811