📥Request context

Request's context was already demonstrated previously. This page gives some tips about general approach to passing objects to handlers. Request context may not always be the best option: it's type-unsafe (you must do explicit type-assertion), it's verbose, . It might sometimes be quite a challenge to update the value in runtime.

Let's consider we need a dynamic web-page. We are going to use the html/template for it. Reading the file with it would be quite expensive and inefficient, but storing it all the time in memory is also not a good choice, as at the development stage we would like to see the changes instantly. In this case, we can simply make our handler a method to a structure, which would contain our *html.Template and mutex in order to synchronize access:

import (
	"html/template"
	"log"
	"sync"

	"github.com/indigo-web/indigo"
	"github.com/indigo-web/indigo/http"
	"github.com/indigo-web/indigo/router/inbuilt"
)

type Home struct {
	mu sync.RWMutex
	tmpl *template.Template
}

func NewHome() *Home {
	// initialize the Home here
}

func (h *Home) Get(request *http.Request) *http.Response {
	h.mu.RLock()
	defer h.mu.RUnlock()

	resp := request.Respond()
	if err := h.tmpl.Execute(resp, "some value"); err != nil {
		return http.Error(request, err)
	}

	return resp
}

func (h *Home) ReloadTemplate(request *http.Request) *http.Response {
	h.mu.Lock()
	defer h.mu.Unlock()
	// reload the template here
}

func main() {
	home := NewHome()
	
	r := inbuilt.New().
		Get("/", home.Get).
		Get("/reload-template", home.ReloadTemplate)

	log.Fatal(
		indigo.New(":8080").Serve(r),
	)
}

Simply share the same underlying structure for multiple handlers and protect it by mutex. This is currently the only way to do DI.

Last updated