Hi,
how do you guys handle “service injection” concept in go webserver backends
- do you propagate through middleware provider, by extending Request.Context so handlers can read it from there
- share a global variable (enforce concurrency guards)
- or do you make a Services trait which has a Tree of dependencies, its a type that probably implements http.Handler, has a chain of handlers to whom it injects to those that need certain services
What is your approach? currently I do this:
package views_provider
import (
"context"
"html/template"
"net/http"
)
const ViewsKey = "VIEWS"
type ViewsProviderKey string
func ViewsProvider(root *template.Template) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), ViewsProviderKey(ViewsKey), root)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
}
func Lookup() ViewsProviderKey {
return ViewsProviderKey(ViewsKey)
}
use:
views, ok := req.Context().Value(views_provider.Lookup()).(*template.Template)
bootstrap server:
func (r *Router) Bootstrap() {
// global middlewares
r.Use(
middleware.Recoverer,
reqsize.RequestSize(1),
views_provider.ViewsProvider(r.ViewsEngine),
store_provider.SessionProvider(SESSION_STORE),
)
for _, registry := range RegistryList {
registry(r)
}
}
does that look discouraged or okay?