gis/server/httputil/httputil.go

63 lines
1.5 KiB
Go

package httputil
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"github.com/go-playground/validator/v10"
)
func WriteJSON(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
_ = json.NewEncoder(w).Encode(data)
}
func DecodeJSON[T any](w http.ResponseWriter, r *http.Request) (T, error) {
var v T
r.Body = http.MaxBytesReader(w, r.Body, 1<<20)
dec := json.NewDecoder(r.Body)
dec.DisallowUnknownFields()
if err := dec.Decode(&v); err != nil {
return v, err
}
return v, nil
}
func WriteValidationErrors(w http.ResponseWriter, err error) {
var ve validator.ValidationErrors
if !errors.As(err, &ve) {
WriteJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid request"})
return
}
problems := make(map[string]string, len(ve))
for _, fe := range ve {
problems[fe.Field()] = messageForTag(fe)
}
WriteJSON(w, http.StatusBadRequest, map[string]any{"errors": problems})
}
func messageForTag(fe validator.FieldError) string {
switch fe.Tag() {
case "required":
return "is required"
case "email":
return "must be a valid email address"
case "min":
return fmt.Sprintf("must be at least %s characters", fe.Param())
case "max":
return fmt.Sprintf("must be at most %s characters", fe.Param())
case "gte":
return fmt.Sprintf("must be %s or greater", fe.Param())
case "lte":
return fmt.Sprintf("must be %s or less", fe.Param())
default:
return "is invalid"
}
}