Generic Light-weight Handler Framework
This is a experimental library. The goal is to evaluate leveraging generics to reduce duplicate code around deserializing and serializing http requests/responses.
GLHF is used in various production apps but caution should be used. We will be continually modifying GLHF.
GLHF is versioned using go modules. To install it, run
go get -u github.com/VauntDev/glhf
GLHF is a simple library that abstracts common http patterns while aiming to not prevent more complex use cases.
GLHF uses an options pattern. Options can be passed directly into the Http Method functions.
i.e glhf.Get(myhandler, WithDefaultContentType("application/proto"))
- WithDefaultContentType: set the default contentType that should be used.
- WithVerbose: enables verbose error responses, useful for developers that are running into error reading/writing http objects.
More options will be added over time, check the godocs for future options.
Request and Response marshaling is handled in glfh by utilizing the following HTTP headers
- Content-Type: GLHF Content-type to determine how to marshal and unmarshal the request and response.
- Accept : GLHF uses the request Accept header to determine what Content-Type should be used by the response.
Currenly glhf only support Application/json
and Application/proto
. The default is Application/json
.
GLHF works with any http router that uses http.handlerFunc
functions.
Standard Library HTTP Mux
mux := http.NewServeMux()
mux.HandleFunc("/todo", glhf.Post(h.CreateTodo))
mux.HandleFunc("/todo/{id}", glhf.Get(h.LookupTodo))
Gorilla mux
mux := mux.NewRouter()
mux.HandleFunc("/todo", glhf.Post(h.CreateTodo))
mux.HandleFunc("/todo/{id}", glhf.Get(h.LookupTodo))
- GLHF router
- cache support RFC 9111
A sample application can be found in the example directory.
The following is an example GET handler. The functions expects an empty body and Todo body in response.
func (h *Handlers) LookupTodo(r *glhf.Request[glhf.EmptyBody], w *glhf.Response[pb.Todo]) {
p := mux.Vars(r.HTTPRequest())
id, ok := p["id"]
if !ok {
w.SetStatus(http.StatusInternalServerError)
return
}
todo, err := h.service.Get(id)
if err != nil {
w.SetStatus(http.StatusNotFound)
return
}
w.Body = todo
log.Println("external handler", w.Body)
w.SetStatus(http.StatusOK)
return
}
The following is an example POST handler. The function expects a Todo body and Todo response.
func (h *Handlers) CreateTodo(r *glhf.Request[pb.Todo], w *glhf.Response[glhf.EmptyBody]) {
t, err := r.Body()
if err != nil {
w.SetStatus(http.StatusBadRequest)
return
}
if err := h.service.Add(t); err != nil {
w.SetStatus(http.StatusInternalServerError)
return
}
w.SetStatus(http.StatusOK)
return
}