validation

package
v0.23.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package validation provides a dependency-free, Laravel-FormRequest-grade request validator for structs and maps.

Two entry points cover most needs:

  • Validate(v) walks a struct's `validate:"..."` tags and applies rules.
  • Map(data, rules) validates a map[string]any (e.g. decoded JSON) against a programmatic Rules table — no struct required.

Field names in errors use the `json` tag when present, otherwise the struct field name.

Struct example:

type RegisterRequest struct {
    Name                 string `json:"name" validate:"required,max=255"`
    Email                string `json:"email" validate:"required,email"`
    Age                  int    `json:"age" validate:"gte=18,lte=120"`
    Password             string `json:"password" validate:"required,min=8"`
    PasswordConfirmation string `json:"password_confirmation"`
    Role                 string `json:"role" validate:"in=admin|user|guest"`
}

var req RegisterRequest
if err := validation.Validate(&req); err != nil {
    var ve validation.ValidationErrors
    if errors.As(err, &ve) {
        // c.JSON(422, validation.Response(ve))
    }
}

The "confirmed" rule pairs a field with "<Field>Confirmation" (or its json "<field>_confirmation"), matching Laravel's password/password_confirmation convention.

Map example (no struct):

data := map[string]any{"email": "bad", "age": 5}
err := validation.Map(data, validation.Rules{
    "email": {"required", "email"},
    "age":   {"required", "integer", "gte=18"},
})

Web integration. validation is a leaf package and never imports web, so to avoid an import cycle it exposes only the response *shape*. Callers wire it:

func (h *Handler) Store(c *web.Context) (any, error) {
    var req RegisterRequest
    if err := c.Bind(&req); err != nil {
        return nil, err
    }
    if err := validation.Validate(&req); err != nil {
        var ve validation.ValidationErrors
        if errors.As(err, &ve) {
            c.JSON(422, validation.Response(ve))
            return nil, nil
        }
        return nil, err
    }
    return req, nil
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Map

func Map(data map[string]any, rules Rules) error

Map validates a map[string]any (e.g. decoded JSON) against a Rules table. Cross-field rules (eqfield/nefield/confirmed) resolve against other keys in the same map. Returns nil or a ValidationErrors.

func MapWith

func MapWith(data map[string]any, rules Rules, msgs Messages) error

MapWith is Map with per-rule message overrides.

func Validate

func Validate(v any) error

Validate reflects over the struct v (or pointer to struct) and applies the rules declared in each field's `validate:"..."` tag. It returns nil when all fields pass, or a ValidationErrors otherwise.

Nested structs and slices of structs tagged `validate:"dive"` are validated recursively; nested errors are reported with dotted/indexed paths such as "address.city" or "items.0.sku".

Field names in errors use the json tag when present, else the Go field name.

func ValidateWith

func ValidateWith(v any, msgs Messages) error

ValidateWith is Validate with per-rule message overrides. See Messages.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder is a fluent helper for constructing a Rules table programmatically without writing the raw string slices by hand:

rules := validation.New().
    Field("email", "required", "email").
    Field("age", "integer", "gte=18").
    Rules()
err := validation.Map(data, rules)

It is purely sugar over the Rules map; both forms validate identically.

func New

func New() *Builder

New returns an empty Builder.

func (*Builder) Field

func (b *Builder) Field(name string, rules ...string) *Builder

Field adds (or appends to) the rule list for name and returns the Builder for chaining. Calling Field twice for the same name appends rules.

func (*Builder) Rules

func (b *Builder) Rules() Rules

Rules returns the accumulated Rules table.

func (*Builder) Validate

func (b *Builder) Validate(data map[string]any) error

Validate runs the accumulated rules against data, equivalent to Map(data, b.Rules()).

type ErrorResponse

type ErrorResponse struct {
	Message string              `json:"message"`
	Errors  map[string][]string `json:"errors"`
}

ErrorResponse is the JSON shape for a 422 Unprocessable Entity response. It is a plain struct with no web dependency, so any HTTP layer can emit it (e.g. c.JSON(422, validation.Response(ve))).

func Response

func Response(e ValidationErrors) ErrorResponse

Response builds an ErrorResponse from ValidationErrors, suitable for a 422 body. The Message mirrors Laravel's default validation response message.

type Messages

type Messages map[string]string

Messages overrides the default message for a given "field.rule" or "rule" key. The most specific key wins: "email.required" beats "required".

Messages{"email.required": "We need your email", "required": "is mandatory"}

type Rules

type Rules map[string][]string

Rules maps a field name to a list of rule expressions, e.g.

Rules{"email": {"required", "email"}, "age": {"integer", "gte=18"}}

It is the programmatic counterpart to struct `validate:"..."` tags and is used by Map for validating decoded JSON without a struct.

type ValidationErrors

type ValidationErrors map[string][]string

ValidationErrors maps a field name to the list of human-readable messages that failed for it. It implements the error interface, so it can flow through ordinary `error` return values and be recovered with errors.As.

func (ValidationErrors) Add

func (e ValidationErrors) Add(field, msg string)

Add appends a message for field.

func (ValidationErrors) Error

func (e ValidationErrors) Error() string

Error implements the error interface. The message is deterministic (fields sorted) so it is stable in logs and tests.

func (ValidationErrors) Fields

func (e ValidationErrors) Fields() []string

Fields returns the field names that have errors, sorted for determinism.

func (ValidationErrors) First

func (e ValidationErrors) First(field string) string

First returns the first error message for field, or "" if there is none.

func (ValidationErrors) Has

func (e ValidationErrors) Has(field string) bool

Has reports whether the given field has at least one error.

func (ValidationErrors) ToMap

func (e ValidationErrors) ToMap() map[string][]string

ToMap returns the field -> messages map. It is a copy, safe for callers to mutate or serialise.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL