Nashboard/server/api.go

78 lines
1.6 KiB
Go
Raw Normal View History

2022-12-11 02:05:03 +03:00
package server
import (
"encoding/json"
"io"
"log"
"net/http"
"runtime/debug"
)
type ApiError struct {
Err string
Status int
}
func (e ApiError) Error() string {
return e.Err
}
type apiFunc func(Context) error
func MakeHTTPHandler(f apiFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := Context{w, r}
if err := f(ctx); err != nil {
if e, ok := err.(ApiError); ok {
log.Println("API ERROR: ", e.Error(), e.Status)
ctx.WriteJSON(e.Status, e)
return
}
log.Println("INTERNAL ERROR: ", err)
debug.PrintStack()
ctx.WriteJSON(500, &ApiError{Err: "internal error", Status: http.StatusInternalServerError})
return
}
}
}
type Context struct {
W http.ResponseWriter
R *http.Request
}
func (c Context) Header(header string, value string) *Context {
c.W.Header().Add(header, value)
return &c
}
func (c Context) ContentType(contentType string) *Context {
return c.Header("Content-Type", contentType)
}
func (c Context) Status(status int) *Context {
c.W.WriteHeader(status)
return &c
}
func (c Context) WriteJSON(status int, v any) error {
c.ContentType("application/json").Status(status)
return json.NewEncoder(c.W).Encode(v)
}
func (c Context) WritePlain(status int, text string) error {
c.ContentType("text/plain").Status(status)
_, err := c.W.Write([]byte(text))
return err
}
func (c Context) WriteBlob(status int, contentType string, blob []byte) error {
c.ContentType(contentType).Status(status)
_, err := c.W.Write(blob)
return err
}
func DecodeJSON(r io.Reader, v any) error {
return json.NewDecoder(r).Decode(v)
}