Skip to main content

Validation

Regius includes a validation system for incoming request bodies and form input, with a rich rule set, custom rules, struct-tag validation, localized error messages, and a request-validation middleware.

Features​

  • Built-in rules: Required, IsEmail, IsURL, IsUUID, IsPhone, IsCreditCard, IsAlpha, IsAlphanumeric, IsNumeric, IsInt, IsFloat, IsDateISO, IsJSON, IsIP, IsBoolean, IsMinLength, IsMaxLength, IsLength, IsRange, NoSpaces, and MatchesPattern
  • Custom rules: Register reusable rules with app.RegisterValidation("name", func(value string) bool) and invoke any rule by name via v.Rule("name", field, value). Built-in rules are pre-registered and can be overridden
  • Struct validation: v.ValidateStruct(s) validates any struct via validate tags, recursing into nested structs, pointers, and slices (nested) with dot-path error keys (Address.City, Items.0.Name)
  • Localized errors: Rule failures record an i18n key + params in v.Details; v.LocalizedErrors(r.Context()) translates them for the request locale, falling back to English
  • Request validation middleware: app.ValidateRequest(regius.ValidationConfig{...}) decodes JSON bodies into a struct (validating its tags) or validates form bodies field by field, then stores the validated struct in the request context

Built-in Rules​

RuleDescription
RequiredValue must be present and non-empty
IsEmailValid email address
IsURLValid URL
IsUUIDValid UUID
IsPhoneValid phone number
IsCreditCardValid credit card number
IsAlphaAlphabetic characters only
IsAlphanumericAlphanumeric characters only
IsNumericNumeric value
IsIntInteger value
IsFloatFloating-point value
IsDateISOISO 8601 date
IsJSONValid JSON
IsIPValid IP address
IsBooleanBoolean value
IsMinLength / IsMaxLength / IsLengthString length constraints
IsRangeNumeric range
NoSpacesValue without spaces
MatchesPatternRegular-expression match

Struct Tags​

v.ValidateStruct(s) validates any struct via validate tags. Supported tags:

  • required, nested, field=name
  • min=N, max=N, len=N, range=N:M
  • oneof=a b c, regex=PATTERN
  • Any registered rule name

Optional rules skip empty values. Nested structs, pointers, and slices are recursed into, producing dot-path error keys such as Address.City or Items.0.Name.

Usage​

Request Validation Middleware​

Apply to a specific route, decoding JSON bodies into a struct:

type SignupInput struct {
Name string `validate:"required,min=2"`
Email string `validate:"required,email"`
Age int `validate:"min=18"`
}

// In routes.go / routes-api.go
r.Post("/signup", app.ValidateRequest(regius.ValidationConfig{
StructType: SignupInput{},
})(a.Handlers.PostSignup))

// In the handler - the decoded, validated input is in the context
func (h *Handlers) PostSignup(w http.ResponseWriter, r *http.Request) {
input, ok := regius.ValidatedFromContext[*SignupInput](r.Context())
if !ok {
h.App.ErrorStatus(w, http.StatusBadRequest)
return
}
// input.Name, input.Email, input.Age are validated...
}

Form Validation​

Form validation with a browser redirect flow (ErrorFormat: "form" stores localized errors in the session and redirects back with 303):

r.Post("/login", app.ValidateRequest(regius.ValidationConfig{
Rules: map[string]string{
"email": "required,email",
"password": "required,min=8",
},
ErrorFormat: "form", // store errors in session + redirect to Referer
})(a.Handlers.PostLogin))

Manual Validation​

v := app.Validator(r.PostForm)
v.Required(r, "email", "password")
v.IsEmail("email", r.Form.Get("email"))
v.IsMinLength("password", r.Form.Get("password"), 8)
if !v.Valid() {
errors := v.LocalizedErrors(r.Context())
// render the form again with errors...
}

Custom Rules​

Register a reusable rule and invoke it by name:

app.RegisterValidation("strong_password", func(value string) bool {
return len(value) >= 12
})

// Then use it by name anywhere
v.Rule("strong_password", "password", r.Form.Get("password"))