Home

Awesome

go-jsval

Validator toolset, with code generation from JSON Schema

Build Status

GoDoc

Description

The go-jsval package is a data validation toolset, with a tool to generate validators in Go from JSON schemas.

Synopsis

Read a schema file and create a validator using jsval command:

jsval -s /path/to/schema.json -o validator.go
jsval -s /path/to/hyperschema.json -o validator.go -p "/links/0/schema" -p "/links/1/schema" -p "/links/2/schema"

Read a schema file and create a validator programatically:

package jsval_test

import (
  "log"

  "github.com/lestrrat-go/jsschema"
  "github.com/lestrrat-go/jsval/builder"
)

func ExampleBuild() {
  s, err := schema.ReadFile(`/path/to/schema.json`)
  if err != nil {
    log.Printf("failed to open schema: %s", err)
    return
  }

  b := builder.New()
  v, err := b.Build(s)
  if err != nil {
    log.Printf("failed to build validator: %s", err)
    return
  }

  var input interface{}
  if err := v.Validate(input); err != nil {
    log.Printf("validation failed: %s", err)
    return
  }
}

Build a validator by hand:

func ExampleManual() {
  v := jsval.Object().
    AddProp(`zip`, jsval.String().RegexpString(`^\d{5}$`)).
    AddProp(`address`, jsval.String()).
    AddProp(`name`, jsval.String()).
    AddProp(`phone_number`, jsval.String().RegexpString(`^[\d-]+$`)).
    Required(`zip`, `address`, `name`)

  var input interface{}
  if err := v.Validate(input); err != nil {
    log.Printf("validation failed: %s", err)
    return
  }
}

Install

go get -u github.com/lestrrat-go/jsval

If you want to install the jsval tool, do

go get -u github.com/lestrrat-go/jsval/cmd/jsval

Features

Can generate validators from JSON Schema definition

The following command creates a file named jsval.go which contains various variables containing *jsval.JSVal structures so you can include them in your code:

jsval -s schema.json -o jsval.go

See the file generated_validator_test.go for a sample generated from JSON Schema schema.

If your document isn't a real JSON schema but contains one or more JSON schema (like JSON Hyper Schema) somewhere inside the document, you can use the -p argument to access a specific portion of a JSON document:

jsval -s hyper.json -p "/links/0" -p "/lnks/1"

This will generate a set of validators, with JSON references within the file hyper.json properly resolved.

Can handle JSON References in JSON Schema definitions

Note: Not very well tested. Test cases welcome

This packages tries to handle JSON References properly. For example, in the schema below, "age" input is validated against the positiveInteger schema:

{
  "definitions": {
    "positiveInteger": {
      "type": "integer",
      "minimum": 0,
    }
  },
  "properties": {
    "age": { "$ref": "#/definitions/positiveInteger" }
  }
}

Run a playground server

jsval server -listen :8080

You can specify a JSON schema, and see what kind of validator gets generated.

Tricks

Specifying structs with values that may or may not be initialized

With maps, it's easy to check if a property exists. But if you are validating a struct, however, all of the fields exist all the time, and you basically cannot detect if you have a missing field to apply defaults, etc.

For such cases you should use the Maybe interface provided in this package:

type Foo struct {
  Name MaybeString `json:"name"`
}

This will declare the value as "optional", and the JSVal validation mechanism does the correct thing to process this field.

References

NameNotes
go-jsschemaJSON Schema implementation
go-jshschemaJSON Hyper Schema implementation
go-jsrefJSON Reference implementation
go-jspointerJSON Pointer implementations