Help us shape the future of Go! Take the 2026 Go Developer Survey

validator

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package validator composes validation rules over a typed payload.

A Rule is a function; a Validator is an ordered list of them:

v := validator.New(
	func(ctx context.Context, o Order) error {
		if validator.IsEmpty(o.ID) {
			return validator.NewRequiredError("id")
		}
		return nil
	},
	func(ctx context.Context, o Order) error {
		if o.Total < 0 {
			return validator.NewInvalidError("total", o.Total)
		}
		return nil
	},
)

if err := v.Validate(ctx, order); err != nil {
	return err
}

Rules run in the order they were given and Validate stops at the first failure, so it reports one problem per call rather than every problem in the payload.

The errors carry a machine-readable ErrorCode alongside their message, which is what lets an HTTP error handler map a validation failure onto a status code without parsing text:

var vErr validator.Error
if errors.As(err, &vErr) && vErr.Code == validator.CodeNotFound {
	w.WriteHeader(http.StatusNotFound)
}

Validate wraps the rule error, so reach for errors.As rather than a type assertion.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContainsKey

func ContainsKey[M ~map[K]V, K comparable, V any](m M, k K) bool

ContainsKey reports whether m holds the key k.

func IsEmpty

func IsEmpty[T comparable](value T) bool

IsEmpty reports whether value equals the zero value of its type. It treats "unset" and "explicitly zero" as the same thing, so a rule built on it cannot tell a missing number from a zero one.

Types

type Error

type Error struct {
	Code    ErrorCode
	Message string
}

Error is a validation failure carrying both a human-readable message and the ErrorCode that classifies it. It implements error.

Validate wraps rule errors, so recover this type with errors.As rather than a type assertion.

Example

Validate wraps the rule error, so recovering the code needs errors.As rather than a type assertion.

package main

import (
	"context"
	"fmt"

	"github.com/diegodesousas/go-devkit/pkg/validator"
	"github.com/pkg/errors"
)

type order struct {
	ID    string
	Total int
}

func main() {
	v := validator.New(func(ctx context.Context, o order) error {
		return validator.NewNotFoundError("order")
	})

	err := v.Validate(context.Background(), order{})

	var vErr validator.Error
	if errors.As(err, &vErr) {
		fmt.Println("code:", vErr.Code)
		fmt.Println("message:", vErr.Message)
	}

}
Output:
code: not_found
message: order not found

func NewInvalidError

func NewInvalidError(fieldName string, value any) Error

NewInvalidError reports that value is not acceptable for fieldName.

func NewNotFoundError

func NewNotFoundError(entity string) Error

NewNotFoundError reports that the named entity does not exist.

func NewRequiredError

func NewRequiredError(fieldName string) Error

NewRequiredError reports that fieldName is mandatory but was not supplied.

func (Error) Error

func (v Error) Error() string

type ErrorCode

type ErrorCode string

ErrorCode classifies a validation failure so that callers can branch on the kind of problem without parsing the message.

const (
	// CodeRequired means a mandatory attribute was absent or empty.
	CodeRequired ErrorCode = "required"
	// CodeInvalid means an attribute was present but its value is not
	// acceptable.
	CodeInvalid ErrorCode = "invalid"
	// CodeNotFound means a referenced entity does not exist.
	CodeNotFound ErrorCode = "not_found"
)

The classes of validation failure this package produces.

type Rule

type Rule[T any] func(ctx context.Context, data T) error

Rule checks one property of data and returns nil when it holds. Returning one of the errors from NewRequiredError, NewInvalidError or NewNotFoundError gives the failure a machine-readable ErrorCode.

type Validator

type Validator[T any] interface {
	Validate(ctx context.Context, data T) error
}

Validator runs a fixed list of rules against a value of type T.

Example (StopsAtFirstFailure)

Rules run in order and Validate stops at the first failure, so a payload with two problems reports only the first.

package main

import (
	"context"
	"fmt"

	"github.com/diegodesousas/go-devkit/pkg/validator"
)

type order struct {
	ID    string
	Total int
}

func main() {
	v := validator.New(
		func(ctx context.Context, o order) error {
			return validator.NewRequiredError("id")
		},
		func(ctx context.Context, o order) error {
			return validator.NewInvalidError("total", o.Total)
		},
	)

	fmt.Println(v.Validate(context.Background(), order{Total: -1}))

}
Output:
err validator: attribute id is required

func New

func New[T any](rules ...Rule[T]) Validator[T]

New returns a Validator that applies rules in the order given.

Example
package main

import (
	"context"
	"fmt"

	"github.com/diegodesousas/go-devkit/pkg/validator"
)

type order struct {
	ID    string
	Total int
}

func main() {
	v := validator.New(
		func(ctx context.Context, o order) error {
			if validator.IsEmpty(o.ID) {
				return validator.NewRequiredError("id")
			}
			return nil
		},
		func(ctx context.Context, o order) error {
			if o.Total < 0 {
				return validator.NewInvalidError("total", o.Total)
			}
			return nil
		},
	)

	fmt.Println(v.Validate(context.Background(), order{ID: "abc", Total: 10}))
	fmt.Println(v.Validate(context.Background(), order{Total: 10}))

}
Output:
<nil>
err validator: attribute id is required

Jump to

Keyboard shortcuts

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