...

Text file src/github.com/qri-io/jsonschema/README.md

Documentation: github.com/qri-io/jsonschema

     1# jsonschema
     2[![Qri](https://img.shields.io/badge/made%20by-qri-magenta.svg?style=flat-square)](https://qri.io)
     3[![GoDoc](https://godoc.org/github.com/qri-io/jsonschema?status.svg)](http://godoc.org/github.com/qri-io/jsonschema)
     4[![License](https://img.shields.io/github/license/qri-io/jsonschema.svg?style=flat-square)](./LICENSE)
     5[![Codecov](https://img.shields.io/codecov/c/github/qri-io/jsonschema.svg?style=flat-square)](https://codecov.io/gh/qri-io/jsonschema)
     6[![CI](https://img.shields.io/circleci/project/github/qri-io/jsonschema.svg?style=flat-square)](https://circleci.com/gh/qri-io/jsonschema)
     7[![Go Report Card](https://goreportcard.com/badge/github.com/qri-io/jsonschema)](https://goreportcard.com/report/github.com/qri-io/jsonschema)
     8
     9golang implementation of the [JSON Schema Specification](http://json-schema.org/), which lets you write JSON that validates some other json. Rad.
    10
    11### Package Features
    12
    13* Encode schemas back to JSON
    14* Supply Your own Custom Validators
    15* Uses Standard Go idioms
    16* Fastest Go implementation of [JSON Schema validators](http://json-schema.org/implementations.html#validators) (draft2019_9 only, (old - draft 7) benchmarks are [here](https://github.com/TheWildBlue/validator-benchmarks) - thanks [@TheWildBlue](https://github.com/TheWildBlue)!)
    17
    18### Getting Involved
    19
    20We would love involvement from more people! If you notice any errors or would
    21like to submit changes, please see our
    22[Contributing Guidelines](./.github/CONTRIBUTING.md).
    23
    24### Developing
    25
    26We've set up a separate document for [developer guidelines](https://github.com/qri-io/jsonschema/blob/master/DEVELOPERS.md)!
    27
    28## Basic Usage
    29
    30Here's a quick example pulled from the [godoc](https://godoc.org/github.com/qri-io/jsonschema):
    31
    32```go
    33package main
    34
    35import (
    36	"encoding/json"
    37	"fmt"
    38
    39	"github.com/qri-io/jsonschema"
    40)
    41
    42func main() {
    43	var schemaData = []byte(`{
    44    "$id": "https://qri.io/schema/",
    45    "$comment" : "sample comment",
    46    "title": "Person",
    47    "type": "object",
    48    "properties": {
    49        "firstName": {
    50            "type": "string"
    51        },
    52        "lastName": {
    53            "type": "string"
    54        },
    55        "age": {
    56            "description": "Age in years",
    57            "type": "integer",
    58            "minimum": 0
    59        },
    60        "friends": {
    61          "type" : "array",
    62          "items" : { "title" : "REFERENCE", "$ref" : "#" }
    63        }
    64    },
    65    "required": ["firstName", "lastName"]
    66  }`)
    67
    68  rs := &Schema{}
    69  if err := json.Unmarshal(schemaData, rs); err != nil {
    70    panic("unmarshal schema: " + err.Error())
    71  }
    72
    73  var valid = []byte(`{
    74    "firstName" : "George",
    75    "lastName" : "Michael"
    76    }`)
    77  errs, err := rs.ValidateBytes(valid)
    78  if err != nil {
    79    panic(err)
    80  }
    81
    82  if len(errs) > 0 {
    83    fmt.Println(errs[0].Error())
    84  }
    85
    86  var invalidPerson = []byte(`{
    87    "firstName" : "Prince"
    88    }`)
    89
    90  errs, err = rs.ValidateBytes(invalidPerson)
    91  if err != nil {
    92    panic(err)
    93  }
    94  if len(errs) > 0 {
    95    fmt.Println(errs[0].Error())
    96  }
    97
    98  var invalidFriend = []byte(`{
    99    "firstName" : "Jay",
   100    "lastName" : "Z",
   101    "friends" : [{
   102      "firstName" : "Nas"
   103      }]
   104    }`)
   105  errs, err = rs.ValidateBytes(invalidFriend)
   106  if err != nil {
   107    panic(err)
   108  }
   109  if len(errs) > 0 {
   110    fmt.Println(errs[0].Error())
   111  }
   112}
   113```
   114
   115## Custom Keywords
   116
   117The [godoc](https://godoc.org/github.com/qri-io/jsonschema) gives an example of how to supply your own validators to extend the standard keywords supported by the spec.
   118
   119It involves three steps that should happen _before_ allocating any Schema instances that use the validator:
   1201. create a custom type that implements the `Keyword` interface
   1212. Load the appropriate draft keyword set (see `draft2019_09_keywords.go`)
   1223. call RegisterKeyword with the keyword you'd like to detect in JSON, and a `KeyMaker` function.
   123
   124
   125```go
   126package main
   127
   128import (
   129  "encoding/json"
   130  "fmt"
   131
   132  "github.com/qri-io/jsonschema"
   133)
   134
   135// your custom validator
   136type IsFoo bool
   137
   138// newIsFoo is a jsonschama.KeyMaker
   139func newIsFoo() Keyword {
   140  return new(IsFoo)
   141}
   142
   143// Validate implements jsonschema.Keyword
   144func (f *IsFoo) Validate(propPath string, data interface{}, errs *[]KeyError) {}
   145
   146// Register implements jsonschema.Keyword
   147func (f *IsFoo) Register(uri string, registry *SchemaRegistry) {}
   148
   149// Resolve implements jsonschema.Keyword
   150func (f *IsFoo) Resolve(pointer jptr.Pointer, uri string) *Schema {
   151  return nil
   152}
   153
   154// ValidateKeyword implements jsonschema.Keyword
   155func (f *IsFoo) ValidateKeyword(ctx context.Context, currentState *ValidationState, data interface{}) {
   156  if str, ok := data.(string); ok {
   157    if str != "foo" {
   158      currentState.AddError(data, fmt.Sprintf("should be foo. plz make '%s' == foo. plz", str))
   159    }
   160  }
   161}
   162
   163func main() {
   164  // register a custom validator by supplying a function
   165  // that creates new instances of your Validator.
   166  jsonschema.RegisterKeyword("foo", newIsFoo)
   167
   168  schBytes := []byte(`{ "foo": true }`)
   169
   170  rs := new(Schema)
   171  if err := json.Unmarshal(schBytes, rs); err != nil {
   172    // Real programs handle errors.
   173    panic(err)
   174  }
   175
   176  errs, err := rs.ValidateBytes([]byte(`"bar"`))
   177  if err != nil {
   178    panic(err)
   179  }
   180
   181  fmt.Println(errs[0].Error())
   182  // Output: /: "bar" should be foo. plz make 'bar' == foo. plz
   183}
   184```
   185

View as plain text