Documentation
¶
Overview ¶
Package jsonschema implements JSON Schema validation, schema generation from Go types, and multi-format input via the rotini package family.
The package follows the conventions of encoding/json: a small set of package-level entry points (Compile, Validate, Generate) for one-shot use, and a compiled *Schema value for amortizing compilation across many validations. Functional options shape compile-time and run-time behavior.
schema, err := jsonschema.Compile(schemaJSON)
if err != nil { return err }
result, err := schema.Validate(instanceJSON)
if err != nil { return err }
if !result.Valid { /* inspect result.Errors */ }
Draft Support ¶
The package targets Draft 2020-12 as its primary draft and supports older drafts via the schema's $schema keyword. Conformance baseline against the official JSON Schema Test Suite at v0.1.0:
Draft Mode Test-suite pass rate Draft 4 read-only 608 / 616 (98.7%) Draft 6 read-only 829 / 835 (99.3%) Draft 7 read-only 917 / 923 (99.3%) Draft 2019-09 read-only 1239 / 1251 (99.0%) Draft 2020-12 read + write 1274 / 1291 (98.7%) ← primary target
"Read-only" means the package compiles and validates schemas authored against that draft; the schema generator (Generate, GenerateBytes, FromType) always emits Draft 2020-12 output. A schema's effective draft is determined by (in order): the $schema keyword at the schema root; the value passed via WithDefaultDraft; DraftDefault.
Type Mapping (Schema Generation) ¶
Generate walks a Go value (or reflect.Type via FromType) and emits a JSON Schema describing it.
Go kind Generated schema
bool {"type": "boolean"}
intN, uintN {"type": "integer"} (with min/max on width)
float32, float64 {"type": "number"}
string {"type": "string"}
[]byte, [N]byte {"type": "string", "contentEncoding": "base64"}
[]T, [N]T {"type": "array", "items": <T>}
map[string]V {"type": "object", "additionalProperties": <V>}
struct {"type": "object", "properties": {...}, "required": [...]}
time.Time {"type": "string", "format": "date-time"}
time.Duration {"type": "integer"} or "format": "duration" via [WithGenerateDurationAsString]
*T <T> by default; anyOf:[null, T] under [WithGenerateNullablePointers]
interface{} / any {} by default; configurable via [WithGenerateInterfaceAsAny]
json.Number {"type": ["number", "string"]}
json.RawMessage {} (any)
encoding.TextMarshaler {"type": "string"}
chan / func / unsafe.Pointer generation error
Self-referential and mutually recursive types are emitted via $defs entries with internal $ref links. Custom emitters (registered via WithCustomEmitter) override the default kind-based mapping for a specific Go type.
Struct Tags ¶
Two tags drive schema generation:
- "json" — standard library semantics: property name, "omitempty" (excluded from "required"), and "-" (skipped).
- "jsonschema" — schema-specific options.
Example:
type User struct {
Name string `json:"name" jsonschema:"required,minLength=1,maxLength=100"`
Email string `json:"email" jsonschema:"required,format=email"`
Age int `json:"age,omitempty" jsonschema:"minimum=0,maximum=150"`
Roles []string `json:"roles" jsonschema:"minItems=1,uniqueItems,enum=admin|editor|viewer"`
}
Options are comma-separated; multi-value options use pipe (`enum=a|b|c`). See the README for the complete option vocabulary.
Strict Modes ¶
Two independent strictness modes are supported:
- WithMetaSchemaValidation — at compile time, validate each schema against its declared $schema meta-schema. Catches typos and malformed keyword values. Default: off (recommended for CI).
- WithFormatAssertion — at validation time, treat the "format" keyword as an assertion rather than an annotation. Default: annotation-only, matching the Draft 2020-12 specification's default vocabulary set.
Output Formats ¶
Result.Output renders a validation result in any of the four formats from Draft 2020-12 §12: OutputFlag, OutputBasic, OutputDetailed, and OutputVerbose. The wire shape matches the spec's output meta-schema (also embedded and exposed via OutputMetaSchema) and is suitable for sending over the network or feeding into downstream tools.
Error Handling ¶
The package surfaces five typed errors, each carrying structured fields and supporting errors.Is / errors.As:
- *CompileError — schema-document problems (malformed JSON, bad keyword shape, unknown vocabulary, ref resolution failure).
- *ValidationError — assertion failure during validation. Multi-error unwrap (Go 1.20+) walks nested causes from compound applicators (anyOf, oneOf, allOf, $ref, ...). Switch on [ValidationError.Keyword] for stable error classification.
- *RefError — $ref or $dynamicRef cannot be resolved.
- *LoaderError — a Loader returned an I/O / network error.
- *FormatError — a value with a "format" keyword failed its validator while format assertion is enabled.
Pointer-typed sentinels (ErrCompile, ErrValidation, ErrRef, ErrLoader, ErrFormat) match instances of their concrete error type via errors.Is. Specific failure conditions are surfaced via the package-level sentinels in [errors.go]: ErrUnknownDraft, ErrUnknownKeyword, ErrUnknownFormat, ErrRefCycle, ErrMaxRefDepth, ErrMaxValidationDepth, ErrInstanceTooLarge, ErrLoaderRejected, ErrSchemaNotCompiled, ErrValidationFailed, ErrNilReader, ErrUnsupportedSchemaShape. Multi-format adapters add ErrInvalidYAML and ErrInvalidTOML.
RenderError produces a human-readable error string with the (forward- looking) signature for source-line-pointer formatting.
Multi-Format Input ¶
In addition to JSON, the package can load schemas and instances written as JSONC, YAML, or TOML via the LoadJSONC, LoadYAML, LoadTOML, ValidateJSONC, ValidateYAML, and ValidateTOML entry points. These adapters delegate to go-rotini/jsonc, go-rotini/yaml, and go-rotini/toml; numeric literals are preserved via encoding/json.Number so number-precision keywords (multipleOf, minimum, maximum, const) evaluate against the original wire form. Multi-format support is part of the main package — there is no dedicated sub-module to import.
Compatibility With encoding/json ¶
The standard library has no schema layer, so there is no "drop-in" surface to mirror. The two libraries integrate at the boundary instead:
- Schema.MarshalJSON returns canonical schema bytes that round-trip through encoding/json.Unmarshal + CompileValue.
- Schema.ValidateAndUnmarshal runs validation and then decodes the validated bytes via encoding/json.Unmarshal in a single call, so a caller can move from "is this JSON valid against my schema?" to "decode it into my struct" without two-pass parsing.
- ValidateTo is the generic counterpart to Schema.ValidateAndUnmarshal and returns the decoded value of type T directly.
OpenAPI 3.1 ¶
The VocabOAS vocabulary and the OASDialectURL meta-schema are registered unconditionally so OpenAPI 3.1 schemas compile cleanly out of the box. A schema declaring OASDialectURL as $schema runs against Draft 2020-12 plus the OAS-specific annotation keywords (discriminator, xml, externalDocs, example).
Bowtie Connector ¶
A standards-conformance connector for the Bowtie cross-implementation JSON Schema test harness ships in the bowtie/ sub-package as a `package main` adapter that speaks Bowtie's stdin/stdout protocol.
DoS Protection ¶
The package ships with four independent guards against adversarial input: WithMaxRefDepth (default 100) caps $ref hop depth per keyword; WithMaxValidationDepth (alias WithMaxDepth, default 1000) caps recursion into nested instances; WithMaxInstanceSize (alias WithMaxDocumentSize) caps instance bytes before parsing; the compiler detects ref cycles at compile time and turns them into lazy edges so they cannot stack-overflow the validator.
Index ¶
- Constants
- Variables
- func GenerateBytes(v any, opts ...GenerateOption) ([]byte, error)
- func MetaSchemaBytes(d Draft) ([]byte, error)
- func MetaSchemaURL(d Draft) string
- func MustValidateTo[T any](schema *Schema, instanceJSON []byte, opts ...Option) T
- func RenderError(schemaSrc, instanceSrc []byte, err error, color ...bool) string
- func ValidateTo[T any](schema *Schema, instanceJSON []byte, opts ...Option) (T, error)
- type Annotation
- type ChainLoader
- type CompileError
- type CompileOption
- func WithBaseURI(uri string) CompileOption
- func WithDefaultDraft(d Draft) CompileOption
- func WithLoader(l Loader) CompileOption
- func WithLoaderTrace(w io.Writer) CompileOption
- func WithMaxRefDepth(n int) CompileOption
- func WithMetaSchemaValidation(b bool) CompileOption
- func WithRefCollisionPolicy(p RefCollisionPolicy) CompileOption
- func WithStrict() CompileOption
- func WithStrictKeywords(b bool) CompileOption
- type Compiler
- func (c *Compiler) AddResource(uri string, schemaJSON []byte) error
- func (c *Compiler) Compile(schemaJSON []byte) (*Schema, error)
- func (c *Compiler) CompileURL(uri string) (*Schema, error)
- func (c *Compiler) CompileValue(v any) (*Schema, error)
- func (c *Compiler) MustCompile(schemaJSON []byte) *Schema
- func (c *Compiler) MustCompileURL(uri string) *Schema
- func (c *Compiler) MustCompileValue(v any) *Schema
- type Draft
- type EmbedLoader
- type FileLoader
- type FormatError
- type FormatValidator
- type GenerateOption
- func WithCustomEmitter[T any](fn func(reflect.Type) *Schema) GenerateOption
- func WithDocReader(src fs.FS) GenerateOption
- func WithGenerateAdditionalPropertiesFalse(b bool) GenerateOption
- func WithGenerateDraft(d Draft) GenerateOption
- func WithGenerateDurationAsString(b bool) GenerateOption
- func WithGenerateExpandedRefs(b bool) GenerateOption
- func WithGenerateID(id string) GenerateOption
- func WithGenerateInterfaceAsAny(b bool) GenerateOption
- func WithGenerateNullablePointers(b bool) GenerateOption
- func WithGenerateOmitDescriptions(b bool) GenerateOption
- func WithGenerateOrderedProperties(b bool) GenerateOption
- func WithGenerateSchemaDeclaration(b bool) GenerateOption
- type Generator
- type HTTPLoader
- type Keyword
- type KeywordBinding
- type Loader
- type LoaderError
- type MapItem
- type MapLoader
- type MapSlice
- type Number
- type Option
- func WithCollectAnnotations(b bool) Option
- func WithContentAssertion(b bool) Option
- func WithCustomFormat(name string, fn func(string) error) Option
- func WithFormatAssertion(b bool) Option
- func WithMaxDepth(n int) Option
- func WithMaxDocumentSize(n int) Option
- func WithMaxErrors(n int) Option
- func WithMaxInstanceSize(n int) Option
- func WithMaxKeyCount(n int) Option
- func WithMaxValidationDepth(n int) Option
- func WithReadOnly(b bool) Option
- func WithStopOnFirstError(b bool) Option
- func WithUnknownFormat(p UnknownFormatPolicy) Option
- func WithWarningSink(w io.Writer) Option
- func WithWriteOnly(b bool) Option
- type OutputFormat
- type RefCollisionPolicy
- type RefError
- type Result
- func Validate(schemaJSON, instanceJSON []byte, opts ...Option) (*Result, error)
- func ValidateJSONC(s *Schema, data []byte, opts ...Option) (*Result, error)
- func ValidateTOML(s *Schema, data []byte, opts ...Option) (*Result, error)
- func ValidateYAML(s *Schema, data []byte, opts ...Option) (*Result, error)
- type Schema
- func Compile(schemaJSON []byte, opts ...CompileOption) (*Schema, error)
- func CompileURL(uri string, opts ...CompileOption) (*Schema, error)
- func CompileValue(schemaValue any, opts ...CompileOption) (*Schema, error)
- func FromType(t reflect.Type, opts ...GenerateOption) (*Schema, error)
- func Generate(v any, opts ...GenerateOption) (*Schema, error)
- func LoadJSON(schemaJSON []byte, opts ...CompileOption) (*Schema, error)
- func LoadJSONC(schemaJSONC []byte, opts ...CompileOption) (*Schema, error)
- func LoadJSONCURL(uri string, opts ...CompileOption) (*Schema, error)
- func LoadJSONCValue(v any, opts ...CompileOption) (*Schema, error)
- func LoadJSONURL(uri string, opts ...CompileOption) (*Schema, error)
- func LoadJSONValue(v any, opts ...CompileOption) (*Schema, error)
- func LoadTOML(schemaTOML []byte, opts ...CompileOption) (*Schema, error)
- func LoadTOMLURL(uri string, opts ...CompileOption) (*Schema, error)
- func LoadTOMLValue(v any, opts ...CompileOption) (*Schema, error)
- func LoadYAML(schemaYAML []byte, opts ...CompileOption) (*Schema, error)
- func LoadYAMLURL(uri string, opts ...CompileOption) (*Schema, error)
- func LoadYAMLValue(v any, opts ...CompileOption) (*Schema, error)
- func MetaSchema(d Draft) (*Schema, error)
- func MustCompile(schemaJSON []byte, opts ...CompileOption) *Schema
- func MustCompileURL(uri string, opts ...CompileOption) *Schema
- func MustCompileValue(schemaValue any, opts ...CompileOption) *Schema
- func MustGenerate(v any, opts ...GenerateOption) *Schema
- func MustLoadJSON(schemaJSON []byte, opts ...CompileOption) *Schema
- func MustLoadJSONC(schemaJSONC []byte, opts ...CompileOption) *Schema
- func MustLoadJSONCURL(uri string, opts ...CompileOption) *Schema
- func MustLoadJSONCValue(v any, opts ...CompileOption) *Schema
- func MustLoadJSONURL(uri string, opts ...CompileOption) *Schema
- func MustLoadJSONValue(v any, opts ...CompileOption) *Schema
- func MustLoadTOML(schemaTOML []byte, opts ...CompileOption) *Schema
- func MustLoadTOMLURL(uri string, opts ...CompileOption) *Schema
- func MustLoadTOMLValue(v any, opts ...CompileOption) *Schema
- func MustLoadYAML(schemaYAML []byte, opts ...CompileOption) *Schema
- func MustLoadYAMLURL(uri string, opts ...CompileOption) *Schema
- func MustLoadYAMLValue(v any, opts ...CompileOption) *Schema
- func OutputMetaSchema() *Schema
- func (s *Schema) Anchors() []string
- func (s *Schema) Bindings() []KeywordBinding
- func (s *Schema) Draft() Draft
- func (s *Schema) ID() string
- func (s *Schema) MarshalJSON() ([]byte, error)
- func (s *Schema) MetaSchemaURI() string
- func (s *Schema) Resources() []string
- func (s *Schema) String() string
- func (s *Schema) Validate(instanceJSON []byte, opts ...Option) (*Result, error)
- func (s *Schema) ValidateAndUnmarshal(instanceJSON []byte, v any, opts ...Option) error
- func (s *Schema) ValidateReader(r io.Reader, opts ...Option) (*Result, error)
- func (s *Schema) ValidateValue(v any, opts ...Option) (*Result, error)
- func (s *Schema) Vocabularies() []string
- type UnknownFormatPolicy
- type ValidationError
- type Vocabulary
Examples ¶
Constants ¶
const ( // VocabCore identifies the meta-keywords vocabulary // ($schema, $id, $ref, $dynamicRef, $defs, $anchor, $dynamicAnchor, // $comment, $vocabulary). VocabCore = "https://json-schema.org/draft/2020-12/vocab/core" // VocabApplicator identifies the keywords that apply subschemas // (allOf, anyOf, properties, items, ...). VocabApplicator = "https://json-schema.org/draft/2020-12/vocab/applicator" // VocabUnevaluated identifies unevaluatedItems / unevaluatedProperties. VocabUnevaluated = "https://json-schema.org/draft/2020-12/vocab/unevaluated" // VocabValidation identifies the assertion keywords (type, enum, ...). VocabValidation = "https://json-schema.org/draft/2020-12/vocab/validation" // VocabFormatAnnot identifies the annotation-only flavor of the // "format" keyword (the Draft 2020-12 default). VocabFormatAnnot = "https://json-schema.org/draft/2020-12/vocab/format-annotation" // VocabFormatAssert identifies the assertion flavor of "format" // (opt-in via [WithFormatAssertion]). VocabFormatAssert = "https://json-schema.org/draft/2020-12/vocab/format-assertion" // VocabContent identifies contentEncoding / contentMediaType / // contentSchema. VocabContent = "https://json-schema.org/draft/2020-12/vocab/content" // VocabMetaData identifies title / description / default / examples / // readOnly / writeOnly / deprecated. VocabMetaData = "https://json-schema.org/draft/2020-12/vocab/meta-data" // VocabOAS identifies the OpenAPI 3.1 base vocabulary that ships with // the OAS dialect ([OASDialectURL]). It contributes the four annotation- // only keywords [discriminator], [xml], [externalDocs], and [example]. // The package registers this vocabulary unconditionally so OpenAPI 3.1 // schemas compile cleanly whether or not their $schema points at the // OAS dialect. VocabOAS = "https://spec.openapis.org/oas/3.1/vocab/base" )
Standard vocabulary URIs (Draft 2020-12).
const ( // OASDialectURL is the canonical URI of the OpenAPI 3.1 Schema Object // dialect's meta-schema. A schema declaring this URL as $schema opts // into Draft 2020-12 plus the [VocabOAS] vocabulary. OASDialectURL = "https://spec.openapis.org/oas/3.1/dialect/base" // OASBaseSchemaURL is the canonical $id of the upstream OpenAPI 3.1 // document schema (the schema that validates OpenAPI documents // themselves, distinct from the dialect that those schemas use). OASBaseSchemaURL = "https://spec.openapis.org/oas/3.1/schema/2022-10-07" )
OAS dialect identifiers for OpenAPI 3.1.
const DraftDefault = Draft202012
DraftDefault is the draft used when neither the schema's $schema keyword nor the caller's WithDefaultDraft specifies one.
Variables ¶
var ( // ErrCompile matches any [*CompileError]. ErrCompile = &CompileError{} // ErrValidation matches any [*ValidationError]. ErrValidation = &ValidationError{} // ErrRef matches any [*RefError]. ErrRef = &RefError{} // ErrLoader matches any [*LoaderError]. ErrLoader = &LoaderError{} // ErrFormat matches any [*FormatError]. ErrFormat = &FormatError{} // ErrUnknownDraft indicates a draft selector that the package does not // recognize (typically [DraftUnknown] passed to a Draft-only API). ErrUnknownDraft = errors.New("jsonschema: unknown draft") // ErrUnknownKeyword indicates a keyword that is not registered for the // active draft and [WithStrictKeywords] is enabled. ErrUnknownKeyword = errors.New("jsonschema: unknown keyword") // ErrUnknownFormat indicates a "format" value with no registered // validator while the unknown-format policy is [UnknownFormatError]. // Surfaced as the [FormatError.Cause] inside the wrapping // [*ValidationError.Cause]. ErrUnknownFormat = errors.New("jsonschema: unknown format") // ErrRefCycle indicates a cyclic $ref chain that the compiler could // not turn into a lazy edge. Reserved for future use; v0.1's compile // path resolves every cycle into a lazy edge bounded at run time by // [WithMaxRefDepth] (which surfaces as [ErrMaxRefDepth]). ErrRefCycle = errors.New("jsonschema: ref cycle detected") // ErrMaxRefDepth indicates a single keyword evaluation followed more // than [WithMaxRefDepth] hops. ErrMaxRefDepth = errors.New("jsonschema: max ref depth exceeded") // ErrMaxValidationDepth indicates the validator recursed past // [WithMaxValidationDepth] levels into nested instances. ErrMaxValidationDepth = errors.New("jsonschema: max validation depth exceeded") // ErrMaxKeyCount indicates an object instance had more keys than the // [WithMaxKeyCount] cap allows. ErrMaxKeyCount = errors.New("jsonschema: max key count exceeded") // ErrInstanceTooLarge indicates an instance document larger than // [WithMaxInstanceSize] was rejected before parsing. ErrInstanceTooLarge = errors.New("jsonschema: instance exceeds size limit") // ErrLoaderRejected indicates a [Loader] declined a URI scheme (e.g. // the default chain rejecting http:// without explicit opt-in). ErrLoaderRejected = errors.New("jsonschema: loader rejected URI scheme") // ErrSchemaNotCompiled indicates a [*Schema] method was called on a // nil receiver, or on a value that was not produced by the compiler // (e.g. a zero-value [Schema] literal). ErrSchemaNotCompiled = errors.New("jsonschema: schema not compiled") // ErrValidationFailed is returned when validation produced no // structured [*ValidationError] but the instance was nevertheless // rejected. ErrValidationFailed = errors.New("jsonschema: validation failed") // ErrNilReader indicates a nil [io.Reader] was passed to // [*Schema.ValidateReader]. ErrNilReader = errors.New("jsonschema: nil reader") // ErrUnsupportedSchemaShape indicates a schema slot held a value the // compiler/runtime cannot evaluate (neither a JSON object nor a // boolean schema). Surfaced as the [CompileError.Cause]. ErrUnsupportedSchemaShape = errors.New("jsonschema: unsupported schema shape") )
Sentinel errors. The pointer-typed sentinels (ErrCompile, ErrValidation, ErrRef, ErrLoader, ErrFormat) match instances of their concrete error type via errors.Is; the package-level errors.New sentinels surface specific failure conditions that do not warrant a structured type.
var ( // ErrInvalidYAML indicates a structural problem in YAML input that the // adapter could not convert to a JSON-compatible value (e.g. unresolved // aliases, cyclic merges, or multi-document streams). ErrInvalidYAML = errors.New("jsonschema: invalid yaml") // ErrInvalidTOML indicates a structural problem in TOML input the // adapter could not represent as a JSON-compatible value (e.g. // integer literal out of range, malformed AST shape). ErrInvalidTOML = errors.New("jsonschema: invalid toml") )
Sentinel errors returned by the multi-format adapters. All errors emitted by these adapters wrap one of these so callers can match via errors.Is.
Functions ¶
func GenerateBytes ¶
func GenerateBytes(v any, opts ...GenerateOption) ([]byte, error)
GenerateBytes returns the JSON-encoded schema for v. Equivalent to Generate followed by Schema.MarshalJSON but exposes the bytes directly for callers that want the wire form (e.g. to write to disk).
func MetaSchemaBytes ¶
MetaSchemaBytes returns the JSON bytes of the canonical meta-schema for d. The bytes are a slice into the package's embedded copy and must be treated as read-only; callers that need a mutable buffer should copy.
Returns ErrUnknownDraft for DraftUnknown or any unrecognized value.
func MetaSchemaURL ¶
MetaSchemaURL returns the canonical URL of the meta-schema for d. It is equivalent to d.MetaSchemaURL() and re-exported as a package-level function for symmetry with MetaSchemaBytes.
func MustValidateTo ¶
MustValidateTo is the panic-on-error variant of ValidateTo. Intended for package-init use of static, well-known instances; tests and one-shot CLIs where a malformed input is a programming error.
func RenderError ¶
RenderError produces a human-readable error string.
When err is a *ValidationError (single or multi-cause), the output emits one structured block per leaf cause with the schema keyword location, the instance pointer, the human-readable message, and — when schemaSrc / instanceSrc are non-empty and the JSON pointer can be resolved against them — a snippet of the offending source line with a caret pointer. When err is a *CompileError, only the schema side is rendered. For other error types the function falls through to err.Error().
Set color to true to wrap error text and the caret in ANSI escape sequences (red for errors; bold for the line snippet header). Color is off by default.
Programmatic callers should not parse the returned string — use errors.Is / errors.As against the typed errors (*CompileError, *ValidationError, *RefError, *LoaderError, *FormatError) and switch on [ValidationError.Keyword] for stable classification.
func ValidateTo ¶
ValidateTo validates instanceJSON against schema and returns the decoded value of type T on success, or the validation error on failure. It is the generic counterpart to *Schema.ValidateAndUnmarshal.
Types ¶
type Annotation ¶
type Annotation struct {
// KeywordLocation is the JSON Pointer to the keyword in the schema that
// produced the annotation (e.g. "/properties/name/title").
KeywordLocation string
// AbsoluteKeywordLocation is the resolved-URL form of KeywordLocation;
// empty unless the schema was loaded from a remote URI.
AbsoluteKeywordLocation string
// InstanceLocation is the JSON Pointer to the instance value that the
// annotation describes.
InstanceLocation string
// Keyword is the bare keyword name (e.g. "title").
Keyword string
// Value is the annotation payload (the keyword's value, by default).
Value any
}
Annotation is a successful keyword annotation produced during validation.
type ChainLoader ¶
type ChainLoader []Loader
ChainLoader tries each Loader in order and returns the first non-rejected result. A rejection is any error that wraps ErrLoaderRejected; any other error short-circuits the chain so that a real I/O failure surfaces.
type CompileError ¶
type CompileError struct {
// KeywordLocation is the JSON Pointer (or URL with fragment) to the
// position in the schema where the problem was found.
KeywordLocation string
// Message is a human-readable description of the problem.
Message string
// Cause carries an optional underlying error (e.g. a Loader I/O
// failure wrapped by the compiler when resolving an external $ref).
Cause error
}
CompileError is returned when a schema document is malformed, references a non-existent vocabulary, or violates a keyword's value constraints (e.g. minLength is a string instead of a non-negative integer).
func (*CompileError) Error ¶
func (e *CompileError) Error() string
Error returns a human-readable representation.
func (*CompileError) Is ¶
func (e *CompileError) Is(target error) bool
Is reports whether target is a *CompileError sentinel.
func (*CompileError) Unwrap ¶
func (e *CompileError) Unwrap() error
Unwrap returns the underlying cause, if any.
type CompileOption ¶
type CompileOption func(*compileOptions)
CompileOption configures how Compile, CompileURL, CompileValue, and the Compiler type process schema documents. Apply options at compiler construction (or per-call); they shape draft selection, ref loading, strictness, and meta-schema handling.
func WithBaseURI ¶
func WithBaseURI(uri string) CompileOption
WithBaseURI sets the base URI for the root schema when the schema does not declare an $id. Useful when compiling a schema fragment loaded from a known URL so that relative refs resolve correctly.
func WithDefaultDraft ¶
func WithDefaultDraft(d Draft) CompileOption
WithDefaultDraft sets the draft used when a schema's $schema keyword is absent. Default: DraftDefault (Draft 2020-12).
func WithLoader ¶
func WithLoader(l Loader) CompileOption
WithLoader sets the Loader used to fetch external $refs. Default: a ChainLoader of the embedded meta-schemas plus an HTTPS-only HTTPLoader.
func WithLoaderTrace ¶
func WithLoaderTrace(w io.Writer) CompileOption
WithLoaderTrace writes one line per Loader fetch to w. Useful for diagnosing $ref resolution. Default: nil (no trace).
func WithMaxRefDepth ¶
func WithMaxRefDepth(n int) CompileOption
WithMaxRefDepth limits how many $ref hops a single keyword evaluation may follow. Guards against pathological recursive schemas. Default: 100.
func WithMetaSchemaValidation ¶
func WithMetaSchemaValidation(b bool) CompileOption
WithMetaSchemaValidation enables compile-time validation of each schema against its declared meta-schema. Catches typos and structural errors early. Default: false (off for performance; recommended in CI).
When the schema declares the OpenAPI 3.1 dialect URL (OASDialectURL) the embedded dialect meta-schema is used; otherwise the standard meta-schema for the schema's draft is used.
func WithRefCollisionPolicy ¶
func WithRefCollisionPolicy(p RefCollisionPolicy) CompileOption
WithRefCollisionPolicy controls behavior when two compiled documents declare the same $id. Default: RefCollisionError (compile fails).
In v0.1, only RefCollisionError is wired — other policy values are reserved for v0.2 and currently behave the same as RefCollisionError.
func WithStrict ¶
func WithStrict() CompileOption
WithStrict is a zero-argument shorthand for WithStrictKeywords(true). Provided for consistency with the rotini sister packages.
func WithStrictKeywords ¶
func WithStrictKeywords(b bool) CompileOption
WithStrictKeywords causes unknown keywords to raise a *CompileError at compile time. Default: unknown keywords are kept as annotations and ignored at validation.
type Compiler ¶
type Compiler struct {
// contains filtered or unexported fields
}
Compiler holds compile-time configuration and a cache of compiled remote schemas. Reuse a Compiler when compiling many schemas that share remote references — the cache amortizes loader I/O.
A Compiler is safe for concurrent use after construction. The cache is keyed by absolute URI; concurrent *Compiler.CompileURL calls for the same URI share a single fetch+compile pipeline via an inline single-flight.
func NewCompiler ¶
func NewCompiler(opts ...CompileOption) *Compiler
NewCompiler returns a fresh *Compiler with the supplied options applied.
Example ¶
ExampleNewCompiler reuses one Compiler across multiple Compile calls so that any external schemas referenced via $ref are fetched once and cached.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
c := jsonschema.NewCompiler()
a, _ := c.Compile([]byte(`{"type":"string"}`))
b, _ := c.Compile([]byte(`{"type":"integer"}`))
r1, _ := a.Validate([]byte(`"x"`))
r2, _ := b.Validate([]byte(`5`))
fmt.Println(r1.Valid, r2.Valid)
}
Output: true true
func (*Compiler) AddResource ¶
AddResource registers a schema document under uri so subsequent compilations resolving that URI can find it without invoking the Loader. The bytes are validated as JSON; the document is parsed lazily when first referenced.
func (*Compiler) Compile ¶
Compile parses and compiles schemaJSON. The result is cached by $id so subsequent calls referencing the same document via $ref short-circuit.
func (*Compiler) CompileURL ¶
CompileURL fetches uri via the compiler's loader and compiles the resulting bytes. Concurrent calls for the same URI share a single fetch+compile pipeline (single-flight); the result is cached so subsequent calls return immediately.
func (*Compiler) CompileValue ¶
CompileValue compiles an already-decoded Go value (an `any` produced by json.Unmarshal — typically a map[string]any tree).
func (*Compiler) MustCompile ¶
MustCompile is the panic-on-error variant of *Compiler.Compile.
func (*Compiler) MustCompileURL ¶
MustCompileURL is the panic-on-error variant of *Compiler.CompileURL.
func (*Compiler) MustCompileValue ¶
MustCompileValue is the panic-on-error variant of *Compiler.CompileValue.
type Draft ¶
type Draft int
Draft enumerates the JSON Schema specification drafts the package recognizes. Use DraftDefault when you need the package's preferred draft; pin to a specific constant when interacting with legacy schemas.
const ( // DraftUnknown is the zero value; it indicates "no draft selected". DraftUnknown Draft = iota // Draft4 corresponds to JSON Schema Draft 4 (2013). Draft4 // Draft6 corresponds to JSON Schema Draft 6 (2017). Draft6 // Draft7 corresponds to JSON Schema Draft 7 (2018). Draft7 // Draft201909 corresponds to JSON Schema Draft 2019-09. Draft201909 // Draft202012 corresponds to JSON Schema Draft 2020-12. Draft202012 )
Recognized drafts.
func DraftFromMetaSchemaURL ¶
DraftFromMetaSchemaURL maps a meta-schema URL back to a Draft constant. Both http:// and https:// variants of the legacy URLs are accepted, and trailing # fragments are tolerated. Returns DraftUnknown when no draft matches.
The OpenAPI 3.1 dialect URL (OASDialectURL) maps to Draft202012 — the dialect is a strict superset of Draft 2020-12, so resolving it to Draft 2020-12 wires the schema into the standard 2020-12 evaluator graph and lets the OAS-specific annotation keywords ride along.
func (Draft) DefsKeyword ¶
DefsKeyword returns the subschema-container keyword name for d. Drafts 4 through 7 used "definitions"; Draft 2019-09 introduced "$defs".
func (Draft) IDKeyword ¶
IDKeyword returns the schema-identifier keyword name for d. Draft 4 spelled it as "id" (no leading $); subsequent drafts use "$id".
func (Draft) MetaSchemaURL ¶
MetaSchemaURL returns the canonical URL of the meta-schema that defines d. Legacy drafts (4/6/7) historically used http://; the modern drafts use https://. Returns the empty string for DraftUnknown.
type EmbedLoader ¶
EmbedLoader wraps an embed.FS so schemas bundled into the binary can be referenced via embed:// URIs (e.g. embed://schemas/user.json resolves to the FS path "schemas/user.json").
type FileLoader ¶
type FileLoader struct {
// Root is the directory file:// URIs resolve against. Required; an
// empty Root disables the loader entirely.
Root string
}
FileLoader resolves file:// URIs against the local filesystem. The Root field is mandatory: any path that escapes Root (via .., absolute paths outside Root, etc.) is rejected. When Root is the empty string, FileLoader refuses every URI (returning ErrLoaderRejected) — callers must opt in explicitly to file-system access.
type FormatError ¶
type FormatError struct {
// Format is the format name (e.g. "date-time", "uuid").
Format string
// Value is the offending source value.
Value string
// Cause carries an optional underlying parser/validator error.
Cause error
}
FormatError is surfaced when a value with a "format" keyword fails its associated format validator (and format assertion is enabled).
func (*FormatError) Error ¶
func (e *FormatError) Error() string
Error returns a human-readable representation.
func (*FormatError) Is ¶
func (e *FormatError) Is(target error) bool
Is reports whether target is a *FormatError sentinel.
func (*FormatError) Unwrap ¶
func (e *FormatError) Unwrap() error
Unwrap returns the underlying cause, if any.
type FormatValidator ¶
FormatValidator validates a string against a named format. It returns nil when the value conforms; otherwise it returns a non-nil error (typically a *FormatError but any error is accepted from custom validators).
type GenerateOption ¶
type GenerateOption func(*generateOptions)
GenerateOption configures the schema generator. Pass options to Generate, GenerateBytes, FromType, or NewGenerator; later constructors return a reusable *Generator that amortizes option parsing across many types.
func WithCustomEmitter ¶
func WithCustomEmitter[T any](fn func(reflect.Type) *Schema) GenerateOption
WithCustomEmitter registers a function that emits the schema for values of type T, overriding the default kind-based mapping.
func WithDocReader ¶
func WithDocReader(src fs.FS) GenerateOption
WithDocReader extracts Go doc comments from src files (passed as an fs.FS) and uses them as the description annotation for matching struct fields. The generator parses the source files lazily on first use; if the FS contains no Go sources the option is a no-op.
func WithGenerateAdditionalPropertiesFalse ¶
func WithGenerateAdditionalPropertiesFalse(b bool) GenerateOption
WithGenerateAdditionalPropertiesFalse emits "additionalProperties": false on every generated struct schema. Default: false.
func WithGenerateDraft ¶
func WithGenerateDraft(d Draft) GenerateOption
WithGenerateDraft sets the schema draft to emit. Default: Draft 2020-12.
func WithGenerateDurationAsString ¶
func WithGenerateDurationAsString(b bool) GenerateOption
WithGenerateDurationAsString emits time.Duration as {"type":"string","format":"duration"} instead of integer nanoseconds.
func WithGenerateExpandedRefs ¶
func WithGenerateExpandedRefs(b bool) GenerateOption
WithGenerateExpandedRefs inlines all referenced types instead of using $ref + $defs. Default: false.
func WithGenerateID ¶
func WithGenerateID(id string) GenerateOption
WithGenerateID sets the $id of the generated root schema.
func WithGenerateInterfaceAsAny ¶
func WithGenerateInterfaceAsAny(b bool) GenerateOption
WithGenerateInterfaceAsAny controls how interface{} / any is rendered. true (default): {} (any-value). false: error at generation time so the caller is forced to register a custom emitter.
func WithGenerateNullablePointers ¶
func WithGenerateNullablePointers(b bool) GenerateOption
WithGenerateNullablePointers emits *T as anyOf:[null, T]. Default: false.
func WithGenerateOmitDescriptions ¶
func WithGenerateOmitDescriptions(b bool) GenerateOption
WithGenerateOmitDescriptions suppresses extracting Go doc comments as description strings. Default: false.
func WithGenerateOrderedProperties ¶
func WithGenerateOrderedProperties(b bool) GenerateOption
WithGenerateOrderedProperties controls whether emitted struct schemas preserve Go field declaration order. When true (default), `properties` keys are emitted in declaration order. When false, the generator emits a plain map[string]any whose key order is unspecified.
func WithGenerateSchemaDeclaration ¶
func WithGenerateSchemaDeclaration(b bool) GenerateOption
WithGenerateSchemaDeclaration emits "$schema" on the root of generated schemas. Default: true.
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator is the configurable schema-from-Go-types worker. Reuse a single Generator when you have many types to describe with the same options; option parsing happens once at construction.
A Generator is safe for concurrent use: it carries only immutable configuration plus a lazy doc-comment cache that is built on first use behind a sync.Once.
func NewGenerator ¶
func NewGenerator(opts ...GenerateOption) *Generator
NewGenerator returns a fresh *Generator with the supplied options applied. Options that are unset inherit their documented defaults (matching the package-level Generate entry points).
func (*Generator) FromType ¶
FromType generates the schema for the named reflect.Type.
func (*Generator) GenerateBytes ¶
GenerateBytes returns the JSON-encoded schema for the runtime type of v.
func (*Generator) MustGenerate ¶
MustGenerate is the panic-on-error variant of *Generator.Generate.
type HTTPLoader ¶
type HTTPLoader struct {
// Client is the http.Client used to perform requests. nil falls back
// to a per-call client built from Timeout.
Client *http.Client
// Timeout caps the duration of a single Load. Default: 10 s.
Timeout time.Duration
// MaxBodySize caps the response body size in bytes. Default: 10 MiB.
MaxBodySize int64
// AllowHTTP, when true, permits http:// URLs in addition to https://.
// Default: false.
AllowHTTP bool
// Cache is the in-memory cache TTL for successful responses. 0 disables
// caching (the default).
Cache time.Duration
// RequestDecorator is an optional hook invoked on every outbound
// request — useful for adding authentication headers or API tokens.
RequestDecorator func(*http.Request)
// contains filtered or unexported fields
}
HTTPLoader resolves http:// and https:// URIs over the network. It is HTTPS-only by default; AllowHTTP must be set to true to follow plain http:// URLs. Concurrent requests for the same URI share a single network round-trip via an inline single-flight.
Set the exported fields at construction; treat the value as read-only afterwards. Pass *HTTPLoader (not a copy) so the cache and in-flight state are shared across goroutines.
type Keyword ¶
type Keyword interface {
// Name returns the keyword as it appears in a schema (e.g. "minLength").
Name() string
// SinceDraft returns the first draft in which this keyword exists.
SinceDraft() Draft
// RetiredInDraft returns the draft in which this keyword was removed,
// or [DraftUnknown] if the keyword is still current in 2020-12.
RetiredInDraft() Draft
}
Keyword is the metadata-only interface every JSON Schema keyword satisfies. It carries the keyword's name and the Draft range in which it is recognized. The compiler uses these values to route a schema member to its evaluator; tooling uses them to enumerate the keyword set active for a given draft via KeywordsForDraft / LookupKeyword.
func KeywordsForDraft ¶
KeywordsForDraft returns every keyword that is recognized when the active draft is d, deduplicated by name. A keyword belongs to the result iff its [Keyword.SinceDraft] is ≤ d and its [Keyword.RetiredInDraft] is either DraftUnknown or > d. Returns nil for DraftUnknown.
func LookupKeyword ¶
LookupKeyword finds a keyword by name within the active set for draft d. Returns ok=false when the keyword is not recognized by the package, when it does not exist in the requested draft, or when d is DraftUnknown.
type KeywordBinding ¶
type KeywordBinding struct {
// Name is the keyword identifier (e.g. "minLength", "$ref").
Name string
// Location is the JSON Pointer of the keyword in the source schema.
Location string
// RawValue is the parsed value of the keyword (json.Unmarshal'd).
// May be a map[string]any, []any, json.Number, string, bool, or nil.
RawValue any
}
KeywordBinding is the public projection of one keyword binding extracted at compile time. Returned by *Schema.Bindings for introspection and metadata-only consumers.
type Loader ¶
type Loader interface {
// Load returns the schema bytes for the given URI, or an error
// describing why the URI could not be served. Implementations that do
// not handle a URI should return [ErrLoaderRejected] (wrapped in a
// [*LoaderError]) so a [ChainLoader] can fall through to the next.
Load(uri string) ([]byte, error)
}
Loader fetches the contents of a schema referenced by URI. Implementations must be safe for concurrent use; the compiler may invoke a single Loader from multiple goroutines while resolving a graph of refs.
func DefaultLoader ¶
func DefaultLoader() Loader
DefaultLoader returns the package's default Loader: a ChainLoader containing the embedded standard meta-schemas (so meta-schema refs resolve without network access) followed by an HTTPS-only HTTPLoader with sane defaults.
The returned Loader is shared across calls; callers that need different behavior should build their own ChainLoader.
type LoaderError ¶
type LoaderError struct {
// URI identifies the resource that failed to load.
URI string
// Cause is the underlying I/O / network / parse error.
Cause error
}
LoaderError wraps an underlying I/O / network error from a Loader.
func (*LoaderError) Error ¶
func (e *LoaderError) Error() string
Error returns a human-readable representation.
func (*LoaderError) Is ¶
func (e *LoaderError) Is(target error) bool
Is reports whether target is a *LoaderError sentinel.
func (*LoaderError) Unwrap ¶
func (e *LoaderError) Unwrap() error
Unwrap returns the underlying cause, if any.
type MapItem ¶
type MapItem struct {
// Key is the JSON object member name.
Key string
// Value is the decoded value for this member.
Value any
}
MapItem is a single key-value pair within a MapSlice. JSON object keys are always strings, so [MapItem.Key] is typed as string.
type MapLoader ¶
MapLoader is a Loader backed by a static map of URI to bytes. It is useful in tests, in Compiler.AddResource, and as the storage for the embedded standard meta-schemas in the default loader chain.
Lookups tolerate a trailing # on the requested URI (so an `$id` that ends in `#` matches an entry stored without it, and vice versa).
type MapSlice ¶
type MapSlice []MapItem
MapSlice is an ordered slice of key-value pairs. The schema generator emits MapSlice for properties / definitions / $defs to preserve Go declaration order on round-trip; the validator accepts MapSlice (alongside map[string]any) as the in-memory representation of a JSON object.
type Number ¶
Number is an alias for encoding/json.Number. It preserves the original source text of a JSON number so that precision-sensitive keywords such as multipleOf can compare against the wire form rather than a lossy float64.
The alias lets values flow between this package, the standard library, and the rotini sister packages without a wrapper type at every boundary.
type Option ¶
type Option func(*runOptions)
Option configures a single validation call. Applied to *Schema Validate methods and the package-level Validate function.
Options are evaluated left-to-right; later options override earlier ones for the same field. Most callers will mix WithFormatAssertion, WithStopOnFirstError, WithMaxValidationDepth, and WithCustomFormat.
func WithCollectAnnotations ¶
WithCollectAnnotations controls whether passing keyword annotations are accumulated in [Result.Annotations]. Default: true.
func WithContentAssertion ¶
WithContentAssertion enables contentSchema as an assertion (default: annotation only).
func WithCustomFormat ¶
WithCustomFormat registers a format validator for the given format name.
func WithFormatAssertion ¶
WithFormatAssertion enables "format" as an assertion (default: annotation only). When true, format-validator failures become validation errors.
func WithMaxDepth ¶
WithMaxDepth is a sister-package alias for WithMaxValidationDepth.
func WithMaxDocumentSize ¶
WithMaxDocumentSize is a sister-package alias for WithMaxInstanceSize. Both options write to the same underlying field; later calls win.
func WithMaxErrors ¶
WithMaxErrors caps the number of ValidationError entries collected. After the cap is reached, validation continues (unless WithStopOnFirstError is also set) but additional errors are dropped. Default: 0 (unlimited).
func WithMaxInstanceSize ¶
WithMaxInstanceSize rejects instance documents larger than n bytes before parsing. n <= 0 disables the limit. Default: 0 (no limit). Returns ErrInstanceTooLarge when an instance exceeds the cap.
func WithMaxKeyCount ¶
WithMaxKeyCount caps the number of object keys the validator will visit on any single object instance. When an object has more keys than n, validation surfaces a *ValidationError with Keyword "$maxKeyCount" and Cause ErrMaxKeyCount. Default: 0 (unlimited).
Mitigates DoS via instances with millions of object keys. WithMaxInstanceSize transitively bounds the same attack surface; WithMaxKeyCount is a finer-grain guard for cases where the instance bytes are not the limiting factor (e.g. repeated short keys).
func WithMaxValidationDepth ¶
WithMaxValidationDepth limits recursion into nested objects/arrays to guard against unbounded recursive schemas with adversarial instances. Default: 1000.
func WithReadOnly ¶
WithReadOnly enables direction-aware validation in the "read" direction (the value is being produced as output). Required properties whose schema is annotated `"writeOnly": true` are not enforced because such fields should not appear in output documents.
func WithStopOnFirstError ¶
WithStopOnFirstError short-circuits validation as soon as the first error is found. Equivalent to selecting OutputFlag at the collector level.
Note: applicator branches (anyOf, oneOf, if/then/else) always evaluate every alternative regardless of this option, because the keyword's outcome depends on knowing which branches passed. Short-circuiting applies only at the top-level evaluator and to sibling keywords within a single subschema.
func WithUnknownFormat ¶
func WithUnknownFormat(p UnknownFormatPolicy) Option
WithUnknownFormat controls handling of unrecognized "format" names.
func WithWarningSink ¶
WithWarningSink installs a writer that receives diagnostic messages emitted during validation. v0.1 emits one line per unknown format under the UnknownFormatWarn policy, deduplicated within a single Validate call. Future warning-class diagnostics will write to the same sink. Default: nil (warnings dropped silently).
func WithWriteOnly ¶
WithWriteOnly enables direction-aware validation in the "write" direction (the value is being submitted as input). Required properties whose schema is annotated `"readOnly": true` are not enforced because such fields should not appear in input documents.
type OutputFormat ¶
type OutputFormat int
OutputFormat selects the JSON shape produced by Result.Output per Draft 2020-12 §12.
const ( // OutputFlag emits {"valid": true|false} only. OutputFlag OutputFormat = iota // OutputBasic emits a flat list of assertion outcomes. OutputBasic // OutputDetailed emits a nested tree mirroring the schema's applicator // structure, collapsing groups with no errors. OutputDetailed // OutputVerbose emits the full nested tree, including passing groups. OutputVerbose )
Recognized output formats.
func (OutputFormat) String ¶
func (f OutputFormat) String() string
String returns a human-readable label for f (e.g. "flag", "basic").
type RefCollisionPolicy ¶
type RefCollisionPolicy int
RefCollisionPolicy controls behavior when two schema documents share the same $id within a single compiler.
const ( // RefCollisionError aborts compilation on collision (default). RefCollisionError RefCollisionPolicy = iota // RefCollisionFirstWins keeps the first-registered document and // silently ignores subsequent collisions. RefCollisionFirstWins // RefCollisionLastWins replaces an earlier document with the later one. RefCollisionLastWins )
Recognized ref-collision policies.
func (RefCollisionPolicy) String ¶
func (p RefCollisionPolicy) String() string
String returns a human-readable label for p.
type RefError ¶
type RefError struct {
// Ref is the unresolved reference value as written in the schema.
Ref string
// BaseURI is the base URI in effect when resolution was attempted.
BaseURI string
// Cause carries an optional underlying error (e.g. a Loader fetch
// failure or a JSON-Pointer syntax error).
Cause error
}
RefError is returned when a $ref or $dynamicRef cannot be resolved against any in-scope schema resource.
type Result ¶
type Result struct {
// Valid reports whether the instance validated successfully.
Valid bool
// Errors is the flat list of assertion failures (Basic-format equivalent).
Errors []ValidationError
// Annotations is the flat list of annotations produced by passing keywords.
Annotations []Annotation
}
Result is the structured outcome of a validation run. It is returned by every *Schema Validate-family method; the Result.Output helper renders it into one of the four spec-defined output formats.
Callers should not construct a Result via a struct literal: future versions of this package may add fields and a literal-construction site would silently miss them. Always obtain a *Result from a *Schema Validate-family method.
func Validate ¶
Validate compiles schemaJSON and validates instanceJSON against it in one call. This is a convenience for one-shot use; callers performing multiple validations against the same schema should call Compile once and use *Schema.Validate to amortize compilation cost.
Example ¶
ExampleValidate is the one-shot Compile + Validate convenience for callers that only validate one instance and don't need to retain the compiled *jsonschema.Schema.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
res, err := jsonschema.Validate(
[]byte(`{"type":"integer","minimum":0}`),
[]byte(`-5`),
)
if err != nil {
fmt.Println("err:", err)
return
}
fmt.Println(res.Valid)
}
Output: false
func ValidateJSONC ¶
ValidateJSONC decodes data as JSONC and validates the resulting Go value against s. Number-precision-sensitive keywords see the original numeric text via json.Number.
func ValidateTOML ¶
ValidateTOML decodes data as TOML and validates the resulting Go value against s.
func ValidateYAML ¶
ValidateYAML decodes data as YAML and validates the resulting Go value against s.
Example ¶
ExampleValidateYAML validates a YAML-encoded instance against a JSON schema using the streaming convenience entry point. The schema itself is supplied as JSON (LoadYAML covers schemas authored in YAML).
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schema := jsonschema.MustCompile([]byte(`{"type":"integer","minimum":0}`))
instanceYAML := []byte("42\n")
res, err := jsonschema.ValidateYAML(schema, instanceYAML)
if err != nil {
fmt.Println("err:", err)
return
}
fmt.Println(res.Valid)
}
Output: true
func (*Result) Output ¶
func (r *Result) Output(format OutputFormat) []byte
Output renders the result in the requested format per Draft 2020-12 §12. The four formats are:
- OutputFlag: {"valid": true|false} only.
- OutputBasic: a flat list of assertion outcomes with location info.
- OutputDetailed: a nested tree of failures, collapsing passing groups.
- OutputVerbose: the full nested tree, including passing groups.
The returned bytes are valid JSON and validate against the Draft 2020-12 output meta-schema (https://json-schema.org/draft/2020-12/output/schema).
Example ¶
ExampleResult_Output renders a validation result in OutputFlag form.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schema := jsonschema.MustCompile([]byte(`{"type":"number"}`))
res, _ := schema.Validate([]byte(`"oops"`))
fmt.Println(string(res.Output(jsonschema.OutputFlag)))
}
Output: {"valid":false}
type Schema ¶
type Schema struct {
// contains filtered or unexported fields
}
Schema is a compiled JSON Schema. Once produced by Compile (or its siblings), a Schema is immutable and safe for concurrent validation — callers may freely share a single *Schema across goroutines and call any of the Validate-family methods concurrently.
func Compile ¶
func Compile(schemaJSON []byte, opts ...CompileOption) (*Schema, error)
Compile parses a JSON Schema document and returns a *Schema ready for validation.
The schema's effective draft is determined by the $schema keyword if present; otherwise the package falls back to the value passed via WithDefaultDraft, then DraftDefault.
Example ¶
ExampleCompile shows the one-shot Compile entry point used to amortize schema compilation across many validations.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schema, err := jsonschema.Compile([]byte(`{"type":"string","minLength":3}`))
if err != nil {
fmt.Println("compile error:", err)
return
}
res, err := schema.Validate([]byte(`"hello"`))
if err != nil {
fmt.Println("validate error:", err)
return
}
fmt.Println(res.Valid)
}
Output: true
func CompileURL ¶
func CompileURL(uri string, opts ...CompileOption) (*Schema, error)
CompileURL fetches the schema at uri using the configured Loader (or the default chain) and compiles it.
func CompileValue ¶
func CompileValue(schemaValue any, opts ...CompileOption) (*Schema, error)
CompileValue compiles a schema already represented as a Go value (the result of json.Unmarshal into any, or a jsonc/yaml/toml decode). Useful when the schema is constructed in code or arrives from a non-JSON source.
func FromType ¶
func FromType(t reflect.Type, opts ...GenerateOption) (*Schema, error)
FromType is the type-only counterpart to Generate; useful when the caller has a reflect.Type but no value.
func Generate ¶
func Generate(v any, opts ...GenerateOption) (*Schema, error)
Generate returns a *Schema describing the type of v. The walker honors `json` and `jsonschema` struct tags (see §6 of the requirements doc).
Generate accepts any Go value; only its runtime type is consulted, the value itself is not inspected. Pass a nil-typed value (e.g. `(*MyType)(nil)`) to describe a type without constructing one.
Example ¶
ExampleGenerate emits a JSON Schema describing a Go struct.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
type User struct {
Name string `json:"name" jsonschema:"required,minLength=1"`
}
schema, err := jsonschema.Generate((*User)(nil))
if err != nil {
fmt.Println("err:", err)
return
}
out, _ := schema.MarshalJSON()
fmt.Println(string(out))
}
Output: {"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1}},"required":["name"]}
func LoadJSON ¶
func LoadJSON(schemaJSON []byte, opts ...CompileOption) (*Schema, error)
LoadJSON parses a JSON schema document and compiles it. It is a verbatim alias for Compile provided for naming symmetry with LoadJSONC, LoadYAML, and LoadTOML when callers dispatch on a runtime format label.
func LoadJSONC ¶
func LoadJSONC(schemaJSONC []byte, opts ...CompileOption) (*Schema, error)
LoadJSONC parses a JSONC schema document via github.com/go-rotini/jsonc and compiles it as a JSON Schema. Comments and trailing commas in the source are tolerated; numeric literals retain their original text via json.Number so multipleOf / minimum / maximum evaluate correctly.
Example ¶
ExampleLoadJSONC compiles a schema authored as JSONC (JSON with comments) and validates a JSON instance against it.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schemaJSONC := []byte(`{
// minimum string length is 3
"type": "string",
"minLength": 3
}`)
schema, err := jsonschema.LoadJSONC(schemaJSONC)
if err != nil {
fmt.Println("load error:", err)
return
}
res, _ := schema.Validate([]byte(`"hello"`))
fmt.Println(res.Valid)
}
Output: true
func LoadJSONCURL ¶
func LoadJSONCURL(uri string, opts ...CompileOption) (*Schema, error)
LoadJSONCURL fetches a JSONC schema document from uri using the configured loader and compiles it. Mirrors CompileURL for the JSONC adapter.
func LoadJSONCValue ¶
func LoadJSONCValue(v any, opts ...CompileOption) (*Schema, error)
LoadJSONCValue compiles an already-decoded Go value as if it had been produced by the JSONC adapter. Provided for symmetry with CompileValue when the caller has run their own JSONC decoder.
func LoadJSONURL ¶
func LoadJSONURL(uri string, opts ...CompileOption) (*Schema, error)
LoadJSONURL fetches a JSON schema document from uri using the configured loader and compiles it. Alias for CompileURL.
func LoadJSONValue ¶
func LoadJSONValue(v any, opts ...CompileOption) (*Schema, error)
LoadJSONValue compiles an already-decoded Go value as a JSON schema. Alias for CompileValue.
func LoadTOML ¶
func LoadTOML(schemaTOML []byte, opts ...CompileOption) (*Schema, error)
LoadTOML parses a TOML schema document and compiles it as a JSON Schema.
Example ¶
ExampleLoadTOML compiles a schema authored as TOML and validates a JSON instance against it.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schemaTOML := []byte(`type = "string"
minLength = 1
`)
schema, err := jsonschema.LoadTOML(schemaTOML)
if err != nil {
fmt.Println("load error:", err)
return
}
res, _ := schema.Validate([]byte(`"hi"`))
fmt.Println(res.Valid)
}
Output: true
func LoadTOMLURL ¶
func LoadTOMLURL(uri string, opts ...CompileOption) (*Schema, error)
LoadTOMLURL fetches a TOML schema document from uri using the configured loader and compiles it. Mirrors CompileURL for the TOML adapter.
func LoadTOMLValue ¶
func LoadTOMLValue(v any, opts ...CompileOption) (*Schema, error)
LoadTOMLValue compiles an already-decoded Go value as if it had been produced by the TOML adapter. Provided for symmetry with CompileValue when the caller has run their own TOML decoder.
func LoadYAML ¶
func LoadYAML(schemaYAML []byte, opts ...CompileOption) (*Schema, error)
LoadYAML parses a YAML schema document and compiles it as a JSON Schema. The first document in the stream is used; multi-document streams are rejected with ErrInvalidYAML.
Example ¶
ExampleLoadYAML compiles a schema authored as YAML and validates a JSON instance against it.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schemaYAML := []byte(`type: integer
minimum: 0
maximum: 100
`)
schema, err := jsonschema.LoadYAML(schemaYAML)
if err != nil {
fmt.Println("load error:", err)
return
}
res, _ := schema.Validate([]byte(`42`))
fmt.Println(res.Valid)
}
Output: true
func LoadYAMLURL ¶
func LoadYAMLURL(uri string, opts ...CompileOption) (*Schema, error)
LoadYAMLURL fetches a YAML schema document from uri using the configured loader and compiles it. Mirrors CompileURL for the YAML adapter.
func LoadYAMLValue ¶
func LoadYAMLValue(v any, opts ...CompileOption) (*Schema, error)
LoadYAMLValue compiles an already-decoded Go value as if it had been produced by the YAML adapter. Provided for symmetry with CompileValue when the caller has run their own YAML decoder.
func MetaSchema ¶
MetaSchema returns the compiled *Schema for the canonical meta-schema of d. The result is memoized; repeated calls return the same pointer.
The compile path uses a Compiler backed by the embedded meta-schema MapLoader so refs into the per-vocabulary meta-schemas resolve without network access.
func MustCompile ¶
func MustCompile(schemaJSON []byte, opts ...CompileOption) *Schema
MustCompile is the panic-on-error variant of Compile. Intended for package-init use of static, well-known schemas.
func MustCompileURL ¶
func MustCompileURL(uri string, opts ...CompileOption) *Schema
MustCompileURL is the panic-on-error variant of CompileURL.
func MustCompileValue ¶
func MustCompileValue(schemaValue any, opts ...CompileOption) *Schema
MustCompileValue is the panic-on-error variant of CompileValue.
func MustGenerate ¶
func MustGenerate(v any, opts ...GenerateOption) *Schema
MustGenerate is the panic-on-error variant of Generate. Intended for package-init use of static, well-known types.
func MustLoadJSON ¶
func MustLoadJSON(schemaJSON []byte, opts ...CompileOption) *Schema
MustLoadJSON is the panic-on-error variant of LoadJSON.
func MustLoadJSONC ¶
func MustLoadJSONC(schemaJSONC []byte, opts ...CompileOption) *Schema
MustLoadJSONC is the panic-on-error variant of LoadJSONC.
func MustLoadJSONCURL ¶
func MustLoadJSONCURL(uri string, opts ...CompileOption) *Schema
MustLoadJSONCURL is the panic-on-error variant of LoadJSONCURL.
func MustLoadJSONCValue ¶
func MustLoadJSONCValue(v any, opts ...CompileOption) *Schema
MustLoadJSONCValue is the panic-on-error variant of LoadJSONCValue.
func MustLoadJSONURL ¶
func MustLoadJSONURL(uri string, opts ...CompileOption) *Schema
MustLoadJSONURL is the panic-on-error variant of LoadJSONURL.
func MustLoadJSONValue ¶
func MustLoadJSONValue(v any, opts ...CompileOption) *Schema
MustLoadJSONValue is the panic-on-error variant of LoadJSONValue.
func MustLoadTOML ¶
func MustLoadTOML(schemaTOML []byte, opts ...CompileOption) *Schema
MustLoadTOML is the panic-on-error variant of LoadTOML.
func MustLoadTOMLURL ¶
func MustLoadTOMLURL(uri string, opts ...CompileOption) *Schema
MustLoadTOMLURL is the panic-on-error variant of LoadTOMLURL.
func MustLoadTOMLValue ¶
func MustLoadTOMLValue(v any, opts ...CompileOption) *Schema
MustLoadTOMLValue is the panic-on-error variant of LoadTOMLValue.
func MustLoadYAML ¶
func MustLoadYAML(schemaYAML []byte, opts ...CompileOption) *Schema
MustLoadYAML is the panic-on-error variant of LoadYAML.
func MustLoadYAMLURL ¶
func MustLoadYAMLURL(uri string, opts ...CompileOption) *Schema
MustLoadYAMLURL is the panic-on-error variant of LoadYAMLURL.
func MustLoadYAMLValue ¶
func MustLoadYAMLValue(v any, opts ...CompileOption) *Schema
MustLoadYAMLValue is the panic-on-error variant of LoadYAMLValue.
func OutputMetaSchema ¶
func OutputMetaSchema() *Schema
OutputMetaSchema returns the compiled Draft 2020-12 output-format meta-schema (memoized; embedded). It returns nil only when the embedded bytes fail to compile, which would indicate a build-time mistake.
func (*Schema) Anchors ¶
Anchors returns the plain-name anchors declared in the root resource. Returns nil when the schema is nil or was constructed without a resource map. The returned slice is freshly allocated; callers may mutate it.
func (*Schema) Bindings ¶
func (s *Schema) Bindings() []KeywordBinding
Bindings returns the keyword bindings extracted at compile time. Each binding records the keyword name, its source location, and the keyword's raw value. Returns a fresh slice each call; the slice is safe for callers to mutate, but the embedded RawValue may share storage with the schema's parsed source.
In v0.1, ref-resolution targets are not exposed in the public binding — only Name, Location, and RawValue are populated. v0.2 may extend KeywordBinding with a typed Resolved field.
func (*Schema) ID ¶
ID returns the schema's $id (the absolute URI); empty if no $id was declared at the schema root.
func (*Schema) MarshalJSON ¶
MarshalJSON returns the schema's source bytes. A *Schema therefore embeds transparently in encoding/json.Marshal output.
func (*Schema) MetaSchemaURI ¶
MetaSchemaURI returns the meta-schema URI declared via the $schema keyword, or the canonical URL of the schema's draft when $schema was absent.
func (*Schema) Resources ¶
Resources returns the absolute URIs of every $id-bounded resource the *Schema directly contains: the root URI first, then each nested resource in declaration order. Returns nil when the schema is nil or was constructed without a resource map.
func (*Schema) String ¶
String returns a brief, human-readable summary of the schema for log lines and debug output. Format: `Schema(<draft> [id=<id>] [bytes=<n>])`.
func (*Schema) Validate ¶
Validate validates instanceJSON against the schema and returns a *Result.
Empty input ([]byte{} or all-whitespace) is rejected with an error wrapping io.EOF. The literal `null` is a valid JSON value and validates against any schema that accepts the null type; it is never treated as "no input".
Example ¶
ExampleSchema_Validate demonstrates validating an instance against a previously compiled schema and inspecting the failure list.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schema := jsonschema.MustCompile([]byte(`{
"type":"object",
"properties":{"name":{"type":"string"}},
"required":["name"]
}`))
res, _ := schema.Validate([]byte(`{}`))
fmt.Println(res.Valid, len(res.Errors) > 0)
}
Output: false true
Example (Integer) ¶
ExampleSchema_Validate_integer demonstrates compiling a schema with a numeric type assertion and validating an integer instance.
package main
import (
"fmt"
"github.com/go-rotini/jsonschema"
)
func main() {
schema := jsonschema.MustCompile([]byte(`{"type":"integer"}`))
res, err := schema.Validate([]byte(`42`))
if err != nil {
fmt.Println("err:", err)
return
}
fmt.Println(res.Valid)
}
Output: true
func (*Schema) ValidateAndUnmarshal ¶
ValidateAndUnmarshal validates instanceJSON, then (on success) decodes it into v.
func (*Schema) ValidateReader ¶
ValidateReader streams instance bytes from r and validates them against the schema.
func (*Schema) ValidateValue ¶
ValidateValue validates an already-decoded Go value against the schema.
func (*Schema) Vocabularies ¶
Vocabularies returns the set of vocabulary URIs declared by the schema's effective $vocabulary keyword (or, when absent, the standard set for the schema's draft). Returns a fresh slice each call; safe for callers to mutate.
In v0.1, $vocabulary at the schema root is recognized as a structural keyword but not honored as an opt-in selector — the returned set is always the standard vocabularies for Schema.Draft. When the root schema declares a VocabOAS-aware $schema (the OASDialectURL), VocabOAS is included alongside the draft's standard set. Custom vocabulary registration is reserved for v0.2.
type UnknownFormatPolicy ¶
type UnknownFormatPolicy int
UnknownFormatPolicy controls how the validator reacts to an unrecognized "format" keyword value when format assertion is enabled.
const ( // UnknownFormatIgnore silently accepts unknown formats. This is the // spec default behavior and matches most existing implementations. UnknownFormatIgnore UnknownFormatPolicy = iota // UnknownFormatWarn records an annotation noting the unknown format // but does not fail validation. UnknownFormatWarn // UnknownFormatError fails validation when an unknown format is // encountered. UnknownFormatError )
Recognized unknown-format policies.
func (UnknownFormatPolicy) String ¶
func (p UnknownFormatPolicy) String() string
String returns a human-readable label for p.
type ValidationError ¶
type ValidationError struct {
// KeywordLocation is the JSON Pointer to the failing keyword in the
// schema (e.g. "/properties/name/minLength").
KeywordLocation string
// AbsoluteKeywordLocation is the resolved-URL form of KeywordLocation;
// empty unless the schema was loaded from a remote URI.
AbsoluteKeywordLocation string
// InstanceLocation is the JSON Pointer to the failing value in the
// instance (e.g. "/name").
InstanceLocation string
// Keyword is the bare keyword name that triggered the failure
// (e.g. "minLength"). This is the stable, machine-readable
// classification of the error.
Keyword string
// Message is a human-readable description of the failure.
Message string
// Causes carries nested failures from compound applicators; it is empty
// for leaf assertion failures.
Causes []ValidationError
// Cause carries an optional underlying typed error (e.g. a
// [*FormatError] surfaced by the format assertion). Walked by
// [errors.As] via [ValidationError.Unwrap].
Cause error
}
ValidationError represents a single assertion failure surfaced by the validator. Failures from compound applicators (anyOf, oneOf, $ref, ...) expose their nested causes via [ValidationError.Causes]; the Go 1.20 multi- error errors.Unwrap convention is honored so that errors.Is / errors.As can walk the cause chain.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error returns a human-readable, single-line summary of the failure suitable for log lines. Programmatic callers should switch on [ValidationError.Keyword] rather than parse the message text.
func (*ValidationError) Is ¶
func (e *ValidationError) Is(target error) bool
Is reports whether target is the ErrValidation sentinel. Only the zero-value *ValidationError (i.e. ErrValidation) matches; another concrete *ValidationError does not match unrelated keyword failures via errors.Is. Use errors.As to extract the typed error and inspect [ValidationError.Keyword] for stable classification.
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() []error
Unwrap returns the nested causes for use with Go 1.20+ multi-error errors.Is / errors.As. Returns nil when there are no causes so that the stdlib treats the error as a leaf. When [ValidationError.Cause] is set it is included alongside any nested [Causes].
type Vocabulary ¶
type Vocabulary struct {
// URI is the canonical identifier for the vocabulary (e.g.
// VocabApplicator).
URI string
// Keywords lists every keyword that belongs to the vocabulary. The
// order is informational; the package does not depend on it.
Keywords []Keyword
}
Vocabulary groups a set of keywords under a single URI per Draft 2019-09's vocabulary mechanism. The standard vocabularies are registered at package init time; custom-vocabulary registration is reserved for v0.2.
func Vocabularies ¶
func Vocabularies() []Vocabulary
Vocabularies returns the registered standard vocabularies in declaration order. The returned slice is a defensive copy; the underlying Keyword values are immutable so the per-element copy does not deep-copy them.
Source Files
¶
- compile.go
- content.go
- doc.go
- draft.go
- errors.go
- eval.go
- eval_annotation.go
- eval_applicator.go
- eval_openapi.go
- eval_ref.go
- eval_unevaluated.go
- eval_validation.go
- formats.go
- generator.go
- generator_doc.go
- generator_tags.go
- keywords.go
- loader.go
- loader_os.go
- meta.go
- multifmt.go
- options.go
- output.go
- ref.go
- schema.go
- types.go
- validate.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Command bowtie is the stdin/stdout adapter that exposes github.com/go-rotini/jsonschema to the Bowtie cross-implementation conformance harness (https://bowtie.report).
|
Command bowtie is the stdin/stdout adapter that exposes github.com/go-rotini/jsonschema to the Bowtie cross-implementation conformance harness (https://bowtie.report). |