mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-06-06 23:46:29 +02:00
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
|
package web
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"net/http"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
|
||
|
en "github.com/go-playground/locales/en"
|
||
|
ut "github.com/go-playground/universal-translator"
|
||
|
validator "gopkg.in/go-playground/validator.v9"
|
||
|
en_translations "gopkg.in/go-playground/validator.v9/translations/en"
|
||
|
)
|
||
|
|
||
|
// validate holds the settings and caches for validating request struct values.
|
||
|
var validate = validator.New()
|
||
|
|
||
|
// translator is a cache of locale and translation information.
|
||
|
var translator *ut.UniversalTranslator
|
||
|
|
||
|
func init() {
|
||
|
|
||
|
// Instantiate the english locale for the validator library.
|
||
|
enLocale := en.New()
|
||
|
|
||
|
// Create a value using English as the fallback locale (first argument).
|
||
|
// Provide one or more arguments for additional supported locales.
|
||
|
translator = ut.New(enLocale, enLocale)
|
||
|
|
||
|
// Register the english error messages for validation errors.
|
||
|
lang, _ := translator.GetTranslator("en")
|
||
|
en_translations.RegisterDefaultTranslations(validate, lang)
|
||
|
|
||
|
// Use JSON tag names for errors instead of Go struct names.
|
||
|
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
|
||
|
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
|
||
|
if name == "-" {
|
||
|
return ""
|
||
|
}
|
||
|
return name
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// Decode reads the body of an HTTP request looking for a JSON document. The
|
||
|
// body is decoded into the provided value.
|
||
|
//
|
||
|
// If the provided value is a struct then it is checked for validation tags.
|
||
|
func Decode(r *http.Request, val interface{}) error {
|
||
|
decoder := json.NewDecoder(r.Body)
|
||
|
decoder.DisallowUnknownFields()
|
||
|
if err := decoder.Decode(val); err != nil {
|
||
|
return NewRequestError(err, http.StatusBadRequest)
|
||
|
}
|
||
|
|
||
|
if err := validate.Struct(val); err != nil {
|
||
|
|
||
|
// Use a type assertion to get the real error value.
|
||
|
verrors, ok := err.(validator.ValidationErrors)
|
||
|
if !ok {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// lang controls the language of the error messages. You could look at the
|
||
|
// Accept-Language header if you intend to support multiple languages.
|
||
|
lang, _ := translator.GetTranslator("en")
|
||
|
|
||
|
var fields []FieldError
|
||
|
for _, verror := range verrors {
|
||
|
field := FieldError{
|
||
|
Field: verror.Field(),
|
||
|
Error: verror.Translate(lang),
|
||
|
}
|
||
|
fields = append(fields, field)
|
||
|
}
|
||
|
|
||
|
return &Error{
|
||
|
Err: errors.New("field validation error"),
|
||
|
Status: http.StatusBadRequest,
|
||
|
Fields: fields,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|