I'm new to Go and looking at this the elastic library for go and in the Getting Started example it says "You typically create one client for your app."
What does that mean? Do you create a client in the your main
function and somehow pass it to the functions with context? Do you create a global variable and assign it to the client, like this?
var (
client *elastic.Client
)
func a() {
client.Search()
}
func main() {
c, err := elastic.NewClient()
client = c
}
This gets into a topic that is kinda controversial in go: dependency injection.
Unlike some other languages, we don't usually believe in complicated IOC containers, xml config, and reflection based tools for this kind of thing. I merely follow a few simple principles:
web
package needs a database connection, and an elastic client, it may have a function like Serve(addr string, db database.DB, client *elastic.Client)
where DB
is an interface type for my application's db.The job of main
is essentially to read configuration, create all shared components, and pass them to the various components:
func main(){
var config = readConfig() //flags, json, whatever
var elastic = elastic.NewClient(config.whatever)
var db = database.New(config.Connectionstring)
//now start app components
web.Serve(config.Addr, db, elastic)
}
I find this pattern helps keep my packages separate yet inter-operable. I try to avoid package level variables for anything that needs to change from run to run.
I would create special type that holds these objects.
type AppFactory struct {
Client *http.Client
DatastoreClient *datastore.Client
FileStorage FileStorage
DB DB
}
or you can use context.Context
type key int
const clientKey key = 0
func NewContext(ctx context.Context, client *elastic.Client) context.Context {
return context.WithValue(ctx, clientKey, client)
}
func ClientFromContext(ctx context.Context) *elastic.Client {
client := ctx.Value(clientKey).(*elastic.Client)
return client
}
Personally, I would use context.Context because it is more universal solution.
I don't think it is a good idea to use global variables. Very quickly it can become a problem.