Categorygithub.com/viktordanov/jsonschema
modulepackage
0.1.2
Repository: https://github.com/viktordanov/jsonschema.git
Documentation: pkg.go.dev

# README

jsonschema

Qri GoDoc License Codecov CI Go Report Card

golang implementation of the JSON Schema Specification, which lets you write JSON that validates some other jsoniter. Rad.

Fork information

The standard encoding/json library has been swapped out for the much faster json-iterator. This is merely an experiment to how much the library benefits from that; in fact the tests are broken due to the differences in JSON formatting in the output (still correct, just different formatting which breaks tests)

Package Features

  • Encode schemas back to JSON
  • Supply Your own Custom Validators
  • Uses Standard Go idioms
  • Fastest Go implementation of JSON Schema validators (draft 7 only, 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 (
	"github.com/json-iterator/go"
	"fmt"

	"github.com/qri-io/jsonschema"
)

func main() {
	var schemaData = []byte(`{
      "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.RootSchema{}
	if err := jsoniter.Unmarshal(schemaData, rs); err != nil {
		panic("unmarshal schema: " + err.Error())
	}

	var valid = []byte(`{
    "firstName" : "George",
    "lastName" : "Michael"
    }`)

	if errors, _ := rs.ValidateBytes(valid); len(errors) > 0 {
		panic(errors)
	}

	var invalidPerson = []byte(`{
    "firstName" : "Prince"
    }`)
	if errors, _ := rs.ValidateBytes(invalidPerson); len(errors) > 0 {
                fmt.Println(errors[0].Error())
  }

	var invalidFriend = []byte(`{
    "firstName" : "Jay",
    "lastName" : "Z",
    "friends" : [{
      "firstName" : "Nas"
      }]
    }`)
	if errors, _ := rs.ValidateBytes(invalidFriend); len(errors) > 0 {
	        fmt.Println(errors[0].Error())
  }
}

Custom Validators

The godoc gives an example of how to supply your own validators to extend the standard keywords supported by the spec.

It involves two steps that should happen before allocating any RootSchema instances that use the validator:

  1. create a custom type that implements the Validator interface
  2. call RegisterValidator with the keyword you'd like to detect in JSON, and a ValMaker function.
package main

import (
  "github.com/json-iterator/go"
  "fmt"
  "github.com/qri-io/jsonschema"
)

// your custom validator
type IsFoo bool

// newIsFoo is a jsonschama.ValMaker
func newIsFoo() jsonschema.Validator {
  return new(IsFoo)
}

// Validate implements jsonschema.Validator
func (f IsFoo) Validate(data interface{}) []jsonschema.ValError {
  if str, ok := data.(string); ok {
    if str != "foo" {
      return []jsonschema.ValError{
        {Message: fmt.Sprintf("'%s' is not foo. It should be foo. plz make '%s' == foo. plz", str, str)},
      }
    }
  }
  return nil
}

func main() {
  // register a custom validator by supplying a function
  // that creates new instances of your Validator.
  jsonschema.RegisterValidator("foo", newIsFoo)

  schBytes := []byte(`{ "foo": true }`)

  // parse a schema that uses your custom keyword
  rs := new(jsonschema.RootSchema)
  if err := jsoniter.Unmarshal(schBytes, rs); err != nil {
    // Real programs handle errors.
    panic(err)
  }

  // validate some JSON
  errors := rs.ValidateBytes([]byte(`"bar"`))

  // print le error
  fmt.Println(errs[0].Error())

  // Output: 'bar' is not foo. It should be foo. plz make 'bar' == foo. plz
}

# Functions

AddError creates and appends a ValError to errs.
DataType gives the primitive json type of a standard json-decoded value, plus the special case "integer" for when numbers are whole.
InvalidValueString returns the errored value as a string.
Must turns a JSON string into a *RootSchema, panicing if parsing fails.
NewAdditionalItems creates a new AdditionalItems validator.
NewAdditionalProperties allocates a new AdditionalProperties validator.
NewAllOf creates a new AllOf validator.
NewAnyOf creates a new AnyOf validator.
NewConst creates a new Const Validator.
NewContains creates a new Contains validator.
NewDependencies allocates a new Dependencies validator.
NewElse allocates a new Else validator.
NewEnum creates a new Enum Validator.
NewExclusiveMaximum allocates a new ExclusiveMaximum validator.
NewExclusiveMinimum allocates a new ExclusiveMinimum validator.
NewFormat allocates a new Format validator.
NewIf allocates a new If validator.
NewItems creates a new Items validator.
NewMaximum allocates a new Maximum validator.
NewMaxItems creates a new MaxItems validator.
NewMaxLength allocates a new MaxLength validator.
NewMaxProperties allocates a new MaxProperties validator.
NewMinimum allocates a new Minimum validator.
NewMinItems creates a new MinItems validator.
NewMinLength allocates a new MinLength validator.
NewMinProperties allocates a new MinProperties validator.
NewMultipleOf allocates a new MultipleOf validator.
NewNot creates a new Not validator.
NewOneOf creates a new OneOf validator.
NewPattern allocates a new Pattern validator.
NewPatternProperties allocates a new PatternProperties validator.
NewProperties allocates a new Properties validator.
NewPropertyNames allocates a new PropertyNames validator.
NewRequired allocates a new Required validator.
NewThen allocates a new Then validator.
NewType creates a new Type Validator.
NewUniqueItems creates a new UniqueItems validator.
RegisterValidator adds a validator to DefaultValidators.

# Variables

DefaultSchemaPool is a package level map of schemas by identifier remote references are cached here.
DefaultValidators is a map of JSON keywords to Validators to draw from when decoding schemas.
MaxValueErrStringLen 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

AdditionalItems determines how child instances validate for arrays, and does not directly validate the immediate instance itself.
AdditionalProperties determines how child instances validate for objects, and does not directly validate the immediate instance itself.
BaseValidator is a foundation for building a validator.
Dependency is an instance used only in the Dependencies proprty.
If MUST be a valid JSON Schema.
Items MUST be either a valid JSON Schema or an array of valid JSON Schemas.
RootSchema is a top-level Schema.
Schema is the root JSON-schema struct A JSON Schema vocabulary is a set of keywords defined for a particular purpose.
Type specifies one of the six json primitive types.
ValError represents a single error in an instance of a schema The only absolutely-required property is Message.

# 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.
Validator is an interface for anything that can validate.

# Type aliases

AllOf MUST be a non-empty array.
AnyOf MUST be a non-empty array.
Const MAY be of any type, including null.
Contains validates that an array instance is valid against "Contains" if at least one of its elements is valid against the given schema.
Definitions implements a map of schemas while also satsfying the JSON traversal methods.
Dependencies : [CREF1] This keyword specifies rules that are evaluated if the instance is an object and contains a certain property.
Else MUST be a valid JSON Schema.
Enum validates successfully against this keyword if its value is equal to one of the elements in this keyword's array value.
ExclusiveMaximum MUST be number, representing an exclusive upper limit for a numeric instance.
ExclusiveMinimum MUST be number, representing an exclusive lower limit for a numeric instance.
Format implements semantic validation from section 7 of jsonschema draft 7 The "format" keyword functions as both an annotation (Section 3.3) and as an assertion (Section 3.2).
Maximum MUST be a number, representing an inclusive upper limit for a numeric instance.
MaxItems MUST be a non-negative integer.
MaxLength MUST be a non-negative integer.
MaxProperties MUST be a non-negative integer.
Minimum MUST be a number, representing an inclusive lower limit for a numeric instance.
MinItems MUST be a non-negative integer.
MinLength MUST be a non-negative integer.
MultipleOf MUST be a number, strictly greater than 0.
Not MUST be a valid JSON Schema.
OneOf MUST be a non-empty array.
Pattern MUST be a string.
PatternProperties determines how child instances validate for objects, and does not directly validate the immediate instance itself.
Properties MUST be an object.
PropertyNames checks if every property name in the instance validates against the provided schema if the instance is an object.
Required ensures that for a given object instance, every item in the array is the name of a property in the instance.
Then MUST be a valid JSON Schema.
UniqueItems requires array instance elements be unique If this keyword has boolean value false, the instance validates successfully.
ValMaker is a function that generates instances of a validator.