validate

package
v1.34.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package validate compiles OpenAPI 3.1 schemas with santhosh-tekuri/jsonschema and validates decoded requests against them.

A Compiler holds the full OpenAPI document as one resource. Each operation compiles a synthetic schema of the form

{"type":"object","properties":{"path":{...},"query":{...},"header":{...},
 "body":{"$ref":"spec.json#/components/schemas/X"}},"required":[...]}

whose $refs point into the document with the "spec.json#/..." prefix.

The Compiler is not safe for concurrent use: compile every operation from a single goroutine, as the api registry does in Ready. A compiled Schema is immutable and safe to use from any number of goroutines.

Validation errors become a single ez.EINVALID error whose message lists the failing fields, the first MaxFields of them. Messages never contain the submitted value. Fields returns the same list in structured form.

Index

Constants

View Source
const MaxExactNumber = 64

MaxExactNumber is the length of the longest JSON number literal without an exponent (e or E) that the validator is handed as the client wrote it; longer ones, and ones with an exponent, are handed as canonical text. Exact text keeps bounds and multipleOf checked on the digits a json.Number or big.Int field receives, not on a rounded value. The validator parses every number with big.Rat, whose cost grows with an exponent (1e-999999 takes milliseconds) but without one is linear in a length this caps.

View Source
const MaxFields = 100

MaxFields is the most fields one error lists. A request can fail on as many fields as it has values, so an uncapped list would make the answer many times the size of the request that caused it.

Variables

This section is empty.

Functions

func Coerce

func Coerce(values []string, kind Kind) any

Coerce converts raw parameter values to the JSON value the schema expects. Integers become json.Number in canonical text, those past the int64 and uint64 ranges only up to MaxExactNumber characters; numbers become json.Number as written when no longer than MaxExactNumber and without an exponent, else the shortest text of the nearest float64; a number that is no JSON literal (+5, 007) stays the raw string, where an integer takes it. Booleans accept exactly "true" and "false", arrays take repeated values or one comma-separated value. A value that does not parse is returned as the raw string so validation reports a type error. No values means absent and returns nil.

func DecodeBytes

func DecodeBytes(raw []byte) (any, error)

DecodeBytes decodes a JSON body into any, keeping numbers as json.Number and rejecting trailing data. An empty body returns nil, nil. Errors are ez.EINVALID and never echo the body. An object that repeats a key keeps only its last value (RejectRepeatedKeys refuses such a body).

func NewFieldsError

func NewFieldsError(fields []FieldError) error

NewFieldsError builds a single ez.EINVALID error from fields, sorted by location (path, query, header, body) then name, a run of digits in a name compared as a number, with duplicates removed. The message joins "<name> <message>" with "; ", prefixing parameter names with their location. Only the first MaxFields are kept: the message then ends with "; and <n> more", and Fields returns the ones kept. Returns nil when fields is empty.

func RejectRepeatedKeys

func RejectRepeatedKeys(raw []byte) error

RejectRepeatedKeys returns an ez.EINVALID error when an object of the JSON text raw repeats a key, at any depth and compared after unescaping. DecodeBytes, and so the validator, keep only the last value of a repeated key, while encoding/json decodes every one into the same struct, map or slice. The error never echoes the key. It holds one entry per open array and object, without recursion, and does not bound how deep they nest: the caller does.

Types

type Compiler

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

Compiler compiles operation schemas against one OpenAPI 3.1 document. It is not safe for concurrent use.

func NewCompiler

func NewCompiler(doc json.RawMessage) (*Compiler, error)

NewCompiler loads the OpenAPI 3.1 document as resource "spec.json" and registers the formats compose relies on (uuid and date-time are built in; unknown formats such as int64 or double are ignored by santhosh).

func (*Compiler) Compile

func (c *Compiler) Compile(name string, schema map[string]any) (*Schema, error)

Compile compiles a synthetic operation schema. name must be unique per call (for example "op:<operationId>") and must not be "spec.json".

type FieldError

type FieldError struct {
	In      string
	Name    string
	Message string
}

FieldError is one failing field. In is the request location ("path", "query", "header" or "body"), Name the dotted path inside it ("status", "config.name", "tags.2", or "" for the location itself) and Message the reason, which never contains the submitted value.

func Fields

func Fields(err error) []FieldError

Fields returns the structured field errors carried by err, at most MaxFields of them, or nil.

type Kind

type Kind struct {
	Type  string
	Items *Kind
}

Kind describes the schema type a parameter is coerced to. Type is one of "string", "integer", "number", "boolean" or "array".

type Schema

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

Schema is a compiled operation schema. It is safe for concurrent use.

func (*Schema) Validate

func (s *Schema) Validate(instance any, extra ...FieldError) error

Validate returns nil or an ez.EINVALID error carrying FieldErrors: the schema's violations together with extra, the fields the caller found failing by a check of its own, in one NewFieldsError. Errors that are not schema violations are returned as ez.EINTERNAL, without extra.

Jump to

Keyboard shortcuts

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