diff options
author | Markus Wüstenberg | 2021-10-08 15:00:20 +0200 |
---|---|---|
committer | GitHub | 2021-10-08 15:00:20 +0200 |
commit | 0001b1d60942b8add6879796be7262da8db5772f (patch) | |
tree | 6dd835b94f183d0700c2aef64407b5ab8bf7a039 /http/handler.go | |
parent | 44c274483724ae6771544d805d13124b1f5fb84c (diff) | |
download | gomponents-0001b1d60942b8add6879796be7262da8db5772f.tar.lz gomponents-0001b1d60942b8add6879796be7262da8db5772f.tar.zst gomponents-0001b1d60942b8add6879796be7262da8db5772f.zip |
Add http.Adapt function (#92)
In the new package `http`, an `Adapt` function converts a `Handler` into a `http.HandlerFunc` from the `http` stdlib package.
Diffstat (limited to 'http/handler.go')
-rw-r--r-- | http/handler.go | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/http/handler.go b/http/handler.go new file mode 100644 index 0000000..9f47bff --- /dev/null +++ b/http/handler.go @@ -0,0 +1,42 @@ +// Package http provides adapters to render gomponents in http handlers. +package http + +import ( + "net/http" + + g "github.com/maragudk/gomponents" +) + +// Handler is like http.Handler but returns a Node and an error. +// See Adapt for how errors are translated to HTTP responses. +type Handler = func(http.ResponseWriter, *http.Request) (g.Node, error) + +type errorWithStatusCode interface { + StatusCode() int +} + +// Adapt a Handler to a http.Handlerfunc. +// The returned Node is rendered to the ResponseWriter, in both normal and error cases. +// If the Handler returns an error, and it implements a "StatusCode() int" method, that HTTP status code is sent +// in the response header. Otherwise, the status code http.StatusInternalServerError (500) is used. +func Adapt(h Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + n, err := h(w, r) + if err != nil { + switch v := err.(type) { + case errorWithStatusCode: + w.WriteHeader(v.StatusCode()) + default: + w.WriteHeader(http.StatusInternalServerError) + } + } + + if n == nil { + return + } + + if err := n.Render(w); err != nil { + http.Error(w, "error rendering node: "+err.Error(), http.StatusInternalServerError) + } + } +} |