• Stars
    star
    454
  • Rank 96,350 (Top 2 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 7 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

golang implementation of https://json-schema.org drafts 7 & 2019-09

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 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:

  1. create a custom type that implements the Keyword interface
  2. Load the appropriate draft keyword set (see draft2019_09_keywords.go)
  3. 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
}

More Repositories

1

qri

you're invited to a data party!
Go
1,105
star
2

starlib

qri's standard library for starlark
Go
110
star
3

desktop

Qri Desktop
TypeScript
67
star
4

starpg

A web-based starlark playground
Go
31
star
5

data-stories-scripts

A collection of scripts used for data logging in support of _Data Stories_ on qri.io.
Jupyter Notebook
28
star
6

2017-frontend

qri electron & web frontend
JavaScript
23
star
7

dag

tools for working with directed acyclic graphs (DAGs)
Go
20
star
8

website

qri.io static site
JavaScript
20
star
9

deepdiff

structured data differ with near-linear time complexity
Go
16
star
10

jsonpointer

golang implementation of IETF RFC6901: https://tools.ietf.org/html/rfc6901
Go
16
star
11

dataset

qri dataset definition
Go
15
star
12

rfcs

Request For Comments (RFCs) documenting changes to Qri
12
star
13

wnfs-go

go implementation of fissions web-native file system
Go
11
star
14

p2p-testbed

libp2p & request tracing to make sense of distributed stuff
Go
9
star
15

go-ds-s3

IPFS datastore interface implementation for AWS S3
Go
8
star
16

cafs

content addressed file store interface
Go
7
star
17

matlab

golang matlab level 5 reader / writer library
Go
7
star
18

dataset_sql

Qri SQL support
Go
6
star
19

go-ipld-manifest

DAG manifests for IPLD graphs
Go
6
star
20

walk

Webcrawler/sitemapper
Go
6
star
21

community

๐Ÿ‘‹ Welcome to the Data Bazaar!
5
star
22

zarr-go

Go
5
star
23

startf

Starlark transformation syntax for qri datasets
Go
5
star
24

qri-python

qri python client
Python
5
star
25

registry

MOVED. Registry code now lives at: https://github.com/qri-io/qri/tree/master/registry
Go
4
star
26

varName

Provides Utility for converting length titles into condensed but still recognizable variable names
Go
3
star
27

doggos

doggo nick == [a color]_[doggo breed]
Go
3
star
28

qfs

qri filesystem abstraction
Go
3
star
29

ioes

normalized in, out, error streams for go
Go
3
star
30

frontend

frontend application for our qri.cloud site
TypeScript
3
star
31

papers

HTML
2
star
32

jsontable

Frictionless data jsontable format in go
Go
2
star
33

analytics

distributed analytics
Go
2
star
34

ipfs_camp

ipfs camp workshop tutorial!
1
star
35

homebrew-qri

Qri formula for the Homebrew package manager
Ruby
1
star
36

notes

Notes and ideas about the future of qri
1
star
37

docrun

Run examples found in documentation
Go
1
star
38

errors

golang package for rich errors
Go
1
star
39

apiutil

DEPRECATED - apiutil is a small package for writing user-facing APIs
Go
1
star
40

qri-js

JavaScript
1
star
41

mkpkg

package binaries in platform-specific installers
Go
1
star
42

running-a-remote

examples and guides for running a qri remote
1
star
43

qri_install

easy qri building & installation
Go
1
star
44

dsdiff

Utility for Diffing Datasets, currently a very basic placeholder
Go
1
star