# README
jsonschema
golang implementation of the JSON Schema Specification, which lets you write JSON that validates some other json. Rad.
Package Features
- Encode schemas back to JSON
- Supply Your own Custom Validators
- Uses Standard Go idioms
- Fastest Go implementation of JSON Schema validators (draft2019_9 only, (old — draft 7) benchmarks are here — thanks @TheWildBlue!)
Getting Involved
We would love involvement from more people! If you notice any errors or would like to submit changes, please see our Contributing Guidelines.
Developing
We’ve set up a separate document for developer guidelines!
Basic Usage
Here’s a quick example pulled from the godoc:
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/qri-io/jsonschema"
)
func main() {
ctx := context.Background()
var schemaData = []byte(`{
"$id": "https://qri.io/schema/",
"$comment" : "sample comment",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
},
"friends": {
"type" : "array",
"items" : { "title" : "REFERENCE", "$ref" : "#" }
}
},
"required": ["firstName", "lastName"]
}`)
rs := &jsonschema.Schema{}
if err := json.Unmarshal(schemaData, rs); err != nil {
panic("unmarshal schema: " + err.Error())
}
var valid = []byte(`{
"firstName" : "George",
"lastName" : "Michael"
}`)
errs, err := rs.ValidateBytes(ctx, valid)
if err != nil {
panic(err)
}
if len(errs) > 0 {
fmt.Println(errs[0].Error())
}
var invalidPerson = []byte(`{
"firstName" : "Prince"
}`)
errs, err = rs.ValidateBytes(ctx, invalidPerson)
if err != nil {
panic(err)
}
if len(errs) > 0 {
fmt.Println(errs[0].Error())
}
var invalidFriend = []byte(`{
"firstName" : "Jay",
"lastName" : "Z",
"friends" : [{
"firstName" : "Nas"
}]
}`)
errs, err = rs.ValidateBytes(ctx, invalidFriend)
if err != nil {
panic(err)
}
if len(errs) > 0 {
fmt.Println(errs[0].Error())
}
}
// Output:
// /: {"firstName":"Prince... "lastName" value is required
// /friends/0: {"firstName":"Nas"} "lastName" value is required
Custom Keywords
The godoc gives an example of how to supply your own validators to extend the standard keywords supported by the spec.
It involves three steps that should happen before allocating any Schema instances that use the validator:
- create a custom type that implements the
Keyword
interface - Load the appropriate draft keyword set (see
draft2019_09_keywords.go
) - call RegisterKeyword with the keyword you’d like to detect in JSON, and a
KeyMaker
function.
package main
import (
"context"
"encoding/json"
"fmt"
jptr "github.com/qri-io/jsonpointer"
"github.com/qri-io/jsonschema"
)
// your custom validator
type IsFoo bool
// newIsFoo is a jsonschama.KeyMaker
func newIsFoo() jsonschema.Keyword {
return new(IsFoo)
}
// Validate implements jsonschema.Keyword
func (f *IsFoo) Validate(propPath string, data interface{}, errs *[]jsonschema.KeyError) {}
// Register implements jsonschema.Keyword
func (f *IsFoo) Register(uri string, registry *jsonschema.SchemaRegistry) {}
// Resolve implements jsonschema.Keyword
func (f *IsFoo) Resolve(pointer jptr.Pointer, uri string) *jsonschema.Schema {
return nil
}
// ValidateKeyword implements jsonschema.Keyword
func (f *IsFoo) ValidateKeyword(ctx context.Context, currentState *jsonschema.ValidationState, data interface{}) {
if str, ok := data.(string); ok {
if str != "foo" {
currentState.AddError(data, fmt.Sprintf("should be foo. plz make '%s' == foo. plz", str))
}
}
}
func main() {
// register a custom validator by supplying a function
// that creates new instances of your Validator.
jsonschema.RegisterKeyword("foo", newIsFoo)
// If you register a custom validator, you'll need to manually register
// any other JSON Schema validators you need.
jsonschema.LoadDraft2019_09()
schBytes := []byte(`{ "foo": true }`)
rs := new(jsonschema.Schema)
if err := json.Unmarshal(schBytes, rs); err != nil {
// Real programs handle errors.
panic(err)
}
errs, err := rs.ValidateBytes(context.Background(), []byte(`"bar"`))
if err != nil {
panic(err)
}
fmt.Println(errs[0].Error())
// Output: /: "bar" should be foo. plz make 'bar' == foo. plz
}
# Functions
DataType attempts to parse the underlying data type from the raw data interface.
DataTypeWithHint attempts to parse the underlying data type by leveraging the schema expectations for better results.
FetchSchema downloads and loads a schema from a remote location.
GetKeyword returns a new instance of the keyword.
GetKeywordInsertOrder returns the insert index of the given keyword.
GetKeywordOrder returns the order index of the given keyword or defaults to 1.
GetSchemaRegistry provides an accessor to a globally available schema registry.
InvalidValueString returns the errored value as a string.
IsLocalSchemaID validates if a given id is a local id.
IsNotSupportedKeyword is a utility function to clarify when a given keyword, while expected is not supported.
IsRegisteredKeyword validates if a given prop string is a registered keyword.
IsRegistryLoaded checks if any keywords are present.
LoadDraft2019_09 loads the keywords for schema validation based on draft2019_09 this is also the default keyword set loaded automatically if no other is loaded.
Must turns a JSON string into a *Schema, panicing if parsing fails.
NewAdditionalItems allocates a new AdditionalItems keyword.
NewAdditionalProperties allocates a new AdditionalProperties keyword.
NewAllOf allocates a new AllOf keyword.
NewAnchor allocates a new Anchor keyword.
NewAnyOf allocates a new AnyOf keyword.
NewComment allocates a new Comment keyword.
NewConst allocates a new Const keyword.
NewContains allocates a new Contains keyword.
NewDefault allocates a new Default keyword.
NewDefs allocates a new Defs keyword.
NewDependentRequired allocates a new DependentRequired keyword.
NewDependentSchemas allocates a new DependentSchemas keyword.
NewDescription allocates a new Description keyword.
NewElse allocates a new Else keyword.
NewEnum allocates a new Enum keyword.
NewExamples allocates a new Examples keyword.
NewExclusiveMaximum allocates a new ExclusiveMaximum keyword.
NewExclusiveMinimum allocates a new ExclusiveMinimum keyword.
NewFormat allocates a new Format keyword.
NewID allocates a new Id keyword.
NewIf allocates a new If keyword.
NewItems allocates a new Items keyword.
NewMaxContains allocates a new MaxContains keyword.
NewMaximum allocates a new Maximum keyword.
NewMaxItems allocates a new MaxItems keyword.
NewMaxLength allocates a new MaxLength keyword.
NewMaxProperties allocates a new MaxProperties keyword.
NewMinContains allocates a new MinContains keyword.
NewMinimum allocates a new Minimum keyword.
NewMinItems allocates a new MinItems keyword.
NewMinLength allocates a new MinLength keyword.
NewMinProperties allocates a new MinProperties keyword.
NewMultipleOf allocates a new MultipleOf keyword.
NewNot allocates a new Not keyword.
NewOneOf allocates a new OneOf keyword.
NewPattern allocates a new Pattern keyword.
NewPatternProperties allocates a new PatternProperties keyword.
NewProperties allocates a new Properties keyword.
NewPropertyNames allocates a new PropertyNames keyword.
NewReadOnly allocates a new ReadOnly keyword.
NewRecursiveAnchor allocates a new RecursiveAnchor keyword.
NewRecursiveRef allocates a new RecursiveRef keyword.
NewRef allocates a new Ref keyword.
NewRequired allocates a new Required keyword.
NewSchema allocates a new Schema Keyword/Validator.
NewSchemaURI allocates a new SchemaURI keyword.
NewThen allocates a new Then keyword.
NewTitle allocates a new Title keyword.
NewType allocates a new Type keyword.
NewUnevaluatedItems allocates a new UnevaluatedItems keyword.
NewUnevaluatedProperties allocates a new UnevaluatedProperties keyword.
NewUniqueItems allocates a new UniqueItems keyword.
NewValidationState creates a new ValidationState with the provided location pointers and data instance.
NewVoid allocates a new Void keyword.
NewWriteOnly allocates a new WriteOnly keyword.
RegisterKeyword registers a keyword with the registry.
ResetSchemaRegistry resets the main SchemaRegistry.
SafeResolveURL resolves a string url against the current context url.
SetKeywordOrder assignes a given order to a keyword.
# Variables
MaxKeywordErrStringLen sets how long a value can be before it's length is truncated when printing error strings a special value of -1 disables output trimming.
# Structs
Default defines the default JSON Schema keyword.
Items defines the items JSON Schema keyword.
KeyError represents a single error in an instance of a schema The only absolutely-required property is Message.
PropertyDependency is the internal representation of a dependent property.
RecursiveRef defines the $recursiveRef JSON Schema keyword.
Ref defines the $ref JSON Schema keyword.
Schema is the top-level structure defining a json schema.
SchemaDependency is the internal representation of a dependent schema.
SchemaRegistry maintains a lookup table between schema string references and actual schemas.
Type defines the type JSON Schema keyword.
ValidationState holds the schema validation state The aim is to have one global validation state and use local sub states when evaluating parallel branches TODO(arqu): make sure this is safe for concurrent use.
Void is a placeholder definition for a keyword.
# Interfaces
JSONContainer is an interface that enables tree traversal by listing the immideate children of an object.
JSONPather makes validators traversible by JSON-pointers, which is required to support references in JSON schemas.
Keyword is an interface for anything that can validate.
# Type aliases
AdditionalItems defines the additionalItems JSON Schema keyword.
AdditionalProperties defines the additionalProperties JSON Schema keyword.
AllOf defines the allOf JSON Schema keyword.
Anchor defines the $anchor JSON Schema keyword.
AnyOf defines the anyOf JSON Schema keyword.
Comment defines the comment JSON Schema keyword.
Const defines the const JSON Schema keyword.
Contains defines the contains JSON Schema keyword.
Defs defines the $defs JSON Schema keyword.
DependentRequired defines the dependentRequired JSON Schema keyword.
DependentSchemas defines the dependentSchemas JSON Schema keyword.
Description defines the description JSON Schema keyword.
Else defines the else JSON Schema keyword.
Enum defines the enum JSON Schema keyword.
Examples defines the examples JSON Schema keyword.
ExclusiveMaximum defines the exclusiveMaximum JSON Schema keyword.
ExclusiveMinimum defines the exclusiveMinimum JSON Schema keyword.
Format defines the format JSON Schema keyword.
ID defines the $id JSON Schema keyword.
If defines the if JSON Schema keyword.
KeyMaker is a function that generates instances of a Keyword.
MaxContains defines the maxContains JSON Schema keyword.
Maximum defines the maximum JSON Schema keyword.
MaxItems defines the maxItems JSON Schema keyword.
MaxLength defines the maxLenght JSON Schema keyword.
MaxProperties defines the maxProperties JSON Schema keyword.
MinContains defines the minContains JSON Schema keyword.
Minimum defines the minimum JSON Schema keyword.
MinItems defines the minItems JSON Schema keyword.
MinLength defines the maxLenght JSON Schema keyword.
MinProperties defines the minProperties JSON Schema keyword.
MultipleOf defines the multipleOf JSON Schema keyword.
Not defines the not JSON Schema keyword.
OneOf defines the oneOf JSON Schema keyword.
Pattern defines the pattern JSON Schema keyword.
PatternProperties defines the patternProperties JSON Schema keyword.
Properties defines the properties JSON Schema keyword.
PropertyNames defines the propertyNames JSON Schema keyword.
ReadOnly defines the readOnly JSON Schema keyword.
RecursiveAnchor defines the $recursiveAnchor JSON Schema keyword.
Required defines the required JSON Schema keyword.
SchemaURI defines the $schema JSON Schema keyword.
Then defines the then JSON Schema keyword.
Title defines the title JSON Schema keyword.
UnevaluatedItems defines the unevaluatedItems JSON Schema keyword.
UnevaluatedProperties defines the unevaluatedProperties JSON Schema keyword.
UniqueItems defines the uniqueItems JSON Schema keyword.
WriteOnly defines the writeOnly JSON Schema keyword.