Service propagation from middleware chain to handlers

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?

(post deleted by author)