Documentation
¶
Overview ¶
Package jsonschema is an implementation of the [JSON Schema specification], a JSON-based format for describing the structure of JSON data. The package can be used to read schemas for code generation, and to validate data using the draft 2020-12 specification. Validation with other drafts or custom meta-schemas is not supported.
Construct a Schema as you would any Go struct (for example, by writing a struct literal), or unmarshal a JSON schema into a Schema in the usual way (with encoding/json, for instance). It can then be used for code generation or other purposes without further processing.
Validation ¶
Before using a Schema to validate a JSON value, you must first resolve it by calling Schema.Resolve. The call Resolved.Validate on the result to validate a JSON value. The value must be a Go value that looks like the result of unmarshaling a JSON value into an [any] or a struct. For example, the JSON value
{"name": "Al", "scores": [90, 80, 100]}
could be represented as the Go value
map[string]any{ "name": "Al", "scores": []any{90, 80, 100}, }
or as a value of this type:
type Player struct { Name string `json:"name"` Scores []int `json:"scores"` }
Inference ¶
The For and ForType functions return a Schema describing the given Go type. The type cannot contain any function or channel types, and any map types must have a string key. For example, calling For on the above Player type results in this schema:
{ "properties": { "name": { "type": "string" }, "scores": { "type": "array", "items": {"type": "integer"} } "required": ["name", "scores"], "additionalProperties": {"not": {}} } }
Deviations from the specification ¶
Regular expressions are processed with Go's regexp package, which differs from ECMA 262, most significantly in not supporting back-references. See [this table of differences] for more.
The value of the "format" keyword is recorded in the Schema, but is ignored during validation. It does not even produce [annotations].
[JSON Schema specification]: https://json-schema.org [this table of differences] https://github.com/dlclark/regexp2?tab=readme-ov-file#compare-regexp-and-regexp2 [annotations]: https://json-schema.org/draft/2020-12/json-schema-core#name-annotations
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Equal ¶
Equal reports whether two Go values representing JSON values are equal according to the JSON Schema spec. The values must not contain cycles. See https://json-schema.org/draft/2020-12/json-schema-core#section-4.2.2. It behaves like reflect.DeepEqual, except that numbers are compared according to mathematical equality.
Types ¶
type ResolveOptions ¶ added in v0.34.0
type ResolveOptions struct { // BaseURI is the URI relative to which the root schema should be resolved. // If non-empty, must be an absolute URI (one that starts with a scheme). // It is resolved (in the URI sense; see [url.ResolveReference]) with root's // $id property. // If the resulting URI is not absolute, then the schema cannot contain // relative URI references. BaseURI string // Loader loads schemas that are referred to by a $ref but are not under the // root schema (remote references). // If nil, resolving a remote reference will return an error. Loader Loader // ValidateDefaults determines whether to validate values of "default" keywords // against their schemas. // The [JSON Schema specification] does not require this, but it is // recommended if defaults will be used. // // [JSON Schema specification]: https://json-schema.org/understanding-json-schema/reference/annotations ValidateDefaults bool }
ResolveOptions are options for Schema.Resolve.
type Resolved ¶
type Resolved struct {
// contains filtered or unexported fields
}
A Resolved consists of a Schema along with associated information needed to validate documents against it. A Resolved has been validated against its meta-schema, and all its references (the $ref and $dynamicRef keywords) have been resolved to their referenced Schemas. Call Schema.Resolve to obtain a Resolved from a Schema.
func (*Resolved) ApplyDefaults ¶ added in v0.34.0
ApplyDefaults modifies an instance by applying the schema's defaults to it. If a schema or sub-schema has a default, then a corresponding zero instance value is set to the default.
The JSON Schema specification does not describe how defaults should be interpreted. This method honors defaults only on properties, and only those that are not required. If the instance is a map and the property is missing, the property is added to the map with the default. If the instance is a struct, the field corresponding to the property exists, and its value is zero, the field is set to the default. ApplyDefaults can panic if a default cannot be assigned to a field.
The argument must be a pointer to the instance. (In case we decide that top-level defaults are meaningful.)
It is recommended to first call Resolve with a ValidateDefaults option of true, then call this method, and lastly call Validate.
TODO(jba): consider what defaults on top-level or array instances might mean. TODO(jba): follow $ref and $dynamicRef TODO(jba): apply defaults on sub-schemas to corresponding sub-instances.
type Schema ¶
type Schema struct { // core ID string `json:"$id,omitempty"` Schema string `json:"$schema,omitempty"` Ref string `json:"$ref,omitempty"` Comment string `json:"$comment,omitempty"` Defs map[string]*Schema `json:"$defs,omitempty"` // definitions is deprecated but still allowed. It is a synonym for $defs. Definitions map[string]*Schema `json:"definitions,omitempty"` Anchor string `json:"$anchor,omitempty"` DynamicAnchor string `json:"$dynamicAnchor,omitempty"` DynamicRef string `json:"$dynamicRef,omitempty"` Vocabulary map[string]bool `json:"$vocabulary,omitempty"` // metadata Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` Default json.RawMessage `json:"default,omitempty"` Deprecated bool `json:"deprecated,omitempty"` ReadOnly bool `json:"readOnly,omitempty"` WriteOnly bool `json:"writeOnly,omitempty"` Examples []any `json:"examples,omitempty"` // validation // Use Type for a single type, or Types for multiple types; never both. Type string `json:"-"` Types []string `json:"-"` Enum []any `json:"enum,omitempty"` // Const is *any because a JSON null (Go nil) is a valid value. Const *any `json:"const,omitempty"` MultipleOf *float64 `json:"multipleOf,omitempty"` Minimum *float64 `json:"minimum,omitempty"` Maximum *float64 `json:"maximum,omitempty"` ExclusiveMinimum *float64 `json:"exclusiveMinimum,omitempty"` ExclusiveMaximum *float64 `json:"exclusiveMaximum,omitempty"` MinLength *int `json:"minLength,omitempty"` MaxLength *int `json:"maxLength,omitempty"` Pattern string `json:"pattern,omitempty"` // arrays PrefixItems []*Schema `json:"prefixItems,omitempty"` Items *Schema `json:"items,omitempty"` MinItems *int `json:"minItems,omitempty"` MaxItems *int `json:"maxItems,omitempty"` AdditionalItems *Schema `json:"additionalItems,omitempty"` UniqueItems bool `json:"uniqueItems,omitempty"` Contains *Schema `json:"contains,omitempty"` MinContains *int `json:"minContains,omitempty"` // *int, not int: default is 1, not 0 MaxContains *int `json:"maxContains,omitempty"` UnevaluatedItems *Schema `json:"unevaluatedItems,omitempty"` // objects MinProperties *int `json:"minProperties,omitempty"` MaxProperties *int `json:"maxProperties,omitempty"` Required []string `json:"required,omitempty"` DependentRequired map[string][]string `json:"dependentRequired,omitempty"` Properties map[string]*Schema `json:"properties,omitempty"` PatternProperties map[string]*Schema `json:"patternProperties,omitempty"` AdditionalProperties *Schema `json:"additionalProperties,omitempty"` PropertyNames *Schema `json:"propertyNames,omitempty"` UnevaluatedProperties *Schema `json:"unevaluatedProperties,omitempty"` // logic AllOf []*Schema `json:"allOf,omitempty"` AnyOf []*Schema `json:"anyOf,omitempty"` OneOf []*Schema `json:"oneOf,omitempty"` Not *Schema `json:"not,omitempty"` // conditional If *Schema `json:"if,omitempty"` Then *Schema `json:"then,omitempty"` Else *Schema `json:"else,omitempty"` DependentSchemas map[string]*Schema `json:"dependentSchemas,omitempty"` // other // https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.8 ContentEncoding string `json:"contentEncoding,omitempty"` ContentMediaType string `json:"contentMediaType,omitempty"` ContentSchema *Schema `json:"contentSchema,omitempty"` // https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.7 Format string `json:"format,omitempty"` // contains filtered or unexported fields }
A Schema is a JSON schema object. It corresponds to the 2020-12 draft, as described in https://json-schema.org/draft/2020-12, specifically: - https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01 - https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01
A Schema value may have non-zero values for more than one field: all relevant non-zero fields are used for validation. There is one exception to provide more Go type-safety: the Type and Types fields are mutually exclusive.
Since this struct is a Go representation of a JSON value, it inherits JSON's distinction between nil and empty. Nil slices and maps are considered absent, but empty ones are present and affect validation. For example,
Schema{Enum: nil}
is equivalent to an empty schema, so it validates every instance. But
Schema{Enum: []any{}}
requires equality to some slice element, so it vacuously rejects every instance.
func For ¶
For constructs a JSON schema object for the given type argument.
It is a convenience for ForType.
func ForType ¶
ForType constructs a JSON schema object for the given type. It translates Go types into compatible JSON schema types, as follows:
- strings have schema type "string"
- bools have schema type "boolean"
- signed and unsigned integer types have schema type "integer"
- floating point types have schema type "number"
- slices and arrays have schema type "array", and a corresponding schema for items
- maps with string key have schema type "object", and corresponding schema for additionalProperties
- structs have schema type "object", and disallow additionalProperties. Their properties are derived from exported struct fields, using the struct field json name. Fields that are marked "omitempty" are considered optional; all other fields become required properties.
It returns an error if t contains (possibly recursively) any of the following Go types, as they are incompatible with the JSON schema spec.
- maps with key other than 'string'
- function types
- complex numbers
- unsafe pointers
The cannot be any cycles in the types. TODO(rfindley): we could perhaps just skip these incompatible fields.
func (*Schema) MarshalJSON ¶
func (*Schema) Resolve ¶
func (root *Schema) Resolve(opts *ResolveOptions) (*Resolved, error)
Resolve resolves all references within the schema and performs other tasks that prepare the schema for validation. If opts is nil, the default values are used.
func (*Schema) ResolvedRef ¶ added in v0.34.0
ResolvedRef returns the Schema to which this schema's $ref keyword refers, or nil if it doesn't have a $ref. It returns nil if this schema has not been resolved, meaning that Schema.Resolve was called on it or one of its ancestors.